알고리즘/Algospot

[Algospot] 와일드카드 (문제 ID : WILDCARD)

cho____sh 2020. 1. 11. 17:40
728x90

문제

와일드카드는 다양한 운영체제에서 파일 이름의 일부만으로 파일 이름을 지정하는 방법이다. 와일드카드 문자열은 일반적인 파일명과 같지만, * 나 ? 와 같은 특수 문자를 포함한다.

와일드카드 문자열을 앞에서 한 글자씩 파일명과 비교해서, 모든 글자가 일치했을 때 해당 와일드카드 문자열이 파일명과 매치된다고 하자. 단, 와일드카드 문자열에 포함된 ? 는 어떤 글자와 비교해도 일치한다고 가정하며, * 는 0 글자 이상의 어떤 문자열에도 일치한다고 본다.

예를 들어 와일드 카드 he?p 는 파일명 help 에도, heap 에도 매치되지만, helpp 에는 매치되지 않는다. 와일드 카드 *p* 는 파일명 help 에도, papa 에도 매치되지만, hello 에는 매치되지 않는다.

와일드카드 문자열과 함께 파일명의 집합이 주어질 때, 그 중 매치되는 파일명들을 찾아내는 프로그램을 작성하시오.

 

입력

입력의 첫 줄에는 테스트 케이스의 수 C (1 <= C <= 10) 가 주어진다. 각 테스트 케이스의 첫 줄에는 와일드카드 문자열 W 가 주어지며, 그 다음 줄에는 파일명의 수 N (1 <= N <= 50) 이 주어진다. 그 후 N 줄에 하나씩 각 파일명이 주어진다. 파일명은 공백 없이 알파벳 대소문자와 숫자만으로 이루어져 있으며, 와일드카드는 그 외에 * 와 ? 를 가질 수 있다. 모든 문자열의 길이는 1 이상 100 이하이다.

 

출력

각 테스트 케이스마다 주어진 와일드카드에 매치되는 파일들의 이름을 한 줄에 하나씩 아스키 코드 순서(숫자, 대문자, 소문자 순)대로 출력한다.


까다롭고 어려운 문제였다. 와일드카드와 입력 받은 문자열을 한 글자씩 비교한다. wildcard 함수에서 와일드카도와 문자열의 위치를 입력값으로 받고, dp배열에도 문자열의 위치에 따라 대응되는지를 저장한다. 두 문자가 같은 문자거나 와일드카드의 문자가 '?'라면 위치를 하나씩 증가해서 호출한다. 문제는 와일드카드의 문자가 '*'일 때인데 와일드카드에 문자열을 몇 글자나 대응시켜야 할지가 관건이기 때문이다. 따라서 *가 나오면 wildcard의 위치만 하나 증가하거나 문자열의 위치만 하나씩 증가하는 방식으로 모든 경우를 조사한다. 모든 경우에 해당하지 않으면 일치하지 않는다는 뜻이기 때문에 0을 반환한다.

 

 

코드 원본 : https://github.com/chosh95/STUDY/blob/master/Algospot/WILDCARD.cpp

 

chosh95/STUDY

알고리즘 문제풀이. Contribute to chosh95/STUDY development by creating an account on GitHub.

github.com

C++ 코드

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
int C, N;
string W, S;
int dp[101][101];

int wildcard(int wpos, int spos)
{
	int &ret = dp[wpos][spos];
	if (ret != -1) return ret;

	if(wpos < W.size() && spos < S.size() &&(W[wpos]=='?' || W[wpos]==S[spos])) 
		return ret = wildcard(wpos + 1, spos + 1);
	if (wpos == W.size() && spos == S.size())
		return ret = 1;
	if (W[wpos] == '*') {
		if (wildcard(wpos + 1, spos) || (spos<S.size() && wildcard(wpos, spos + 1))) {
			return ret = 1;
		}
	}
	return ret = 0;
}
int main()
{
	cin >> C;
	while (C--) {
		cin >> W;
		cin >> N;
		vector<string> v;
		while (N--) {
			cin >> S;
			memset(dp, -1, sizeof(dp));
			if (wildcard(0, 0) == 1) v.push_back(S);
		}
		sort(v.begin(), v.end());
		for (int i = 0; i < v.size(); i++)
			cout << v[i] << "\n";
	}
}
728x90