본문 바로가기

Study/Algorithm

[동적계획법]2.와일드카드

종만북 8장 동적계획법. 8.2. WILDCARD

 

https://algospot.com/judge/problem/read/WILDCARD

 

algospot.com :: WILDCARD

Wildcard 문제 정보 문제 와일드카드는 다양한 운영체제에서 파일 이름의 일부만으로 파일 이름을 지정하는 방법이다. 와일드카드 문자열은 일반적인 파일명과 같지만, * 나 ? 와 같은 특수 문자를 포함한다. 와일드카드 문자열을 앞에서 한 글자씩 파일명과 비교해서, 모든 글자가 일치했을 때 해당 와일드카드 문자열이 파일명과 매치된다고 하자. 단, 와일드카드 문자열에 포함된 ? 는 어떤 글자와 비교해도 일치한다고 가정하며, * 는 0 글자 이상의 어떤 문자

algospot.com

 

 

컨셉

처음엔 그냥 *만나면 다음글자 검색하면 되겠지~하고 단순하게 풀다가 예제 세번째에서 틀렸다.

책을 보고 힌트를 얻었다. *를 기준으로 단어를 나눈다. 각 단어마다 검사한다.

예) t*l?*o*r?ng*s  → t* / l?* / o* / r?ng*/ s

 

초안

내가 쓴 답 (정답, 0ms)

...더보기
/**
 * @name    8.2.와일드카드
 * @ID      WILDCARD
 * @date    2019-08-06
 * @author  Sunmon
 */

#include <iostream>
#include <cstring>
#include <set>
using namespace std;

int cache[100][100];
string W, S;
int N;


//와일드카드의 w번째, 문장의 s번째 글자부터 비교하여
//패턴이 끝까지 일치하는지 여부를 리턴한다
bool match(int w, int s)
{
    //base case: 와일드카드 끝까지 검사했을 때 
    if(w==W.length()) return (s == S.length());

    //캐시
    int& ret = cache[w][s];
    if(ret != -1) return ret;

    //?나 글자가 일치하는 경우 -> 다음 글자 검사
    if(W[w] == '?' || W[w] == S[s]) return ret = match(w+1, s+1);

    //*을 만난 경우 다음 와일드카드로 넘기거나, 다음 글자로 넘긴다
    if(W[w] == '*')
        return ret = (match(w+1,s) || (s<S.length() && match(w, s+1)));

    //불일치하는 경우
    return ret = 0;
}

int main()
{
    int C;
    cin >> C;
    while(C--)
    {
        cin >> W >> N;

        //사전 순으로 출력하기 위해 set 사용
        set<string> ans;

        while(N--)
        {
            memset(cache, -1, sizeof(cache));
            cin >> S;
            if(match(0, 0)) ans.insert(S);
        }

        for(auto& a: ans) cout << a << endl;
        ans.clear();
    }
}

 

주의

- 캐시 초기화 하기 :: memset

- answer 초기화 하기 :: 정답으로 쓸 변수, 컨테이너

 

 

'Study > Algorithm' 카테고리의 다른 글

[동적계획법] 4. LIS (미완)  (0) 2019.08.06
[동적계획법] 3. 삼각형 위의 최대 경로  (0) 2019.08.06
[동적계획법] 1.외발뛰기  (0) 2019.08.04
[동적계획법] 0. 동적 계획법  (0) 2019.08.04
스택(Stack)  (0) 2018.07.24