thumbnail
cd ..
root@blog:~/posts/ 202209

종만북 와일드 카드(WildCard) C++ 풀이 (코드제공)

#Algorithm#KOR#Cpp
2022.09.12.

1. 문제 설정 확인

종만북 문제 링크 : WildCard

이 문제에선 와일드카드가 문자열 안에 포함되어있는 (예 : “app*e”) 문자열이 다른 문자 (예 : “apple”)과 같다고 정의될 수 있는지 판단하는 문제다.

솔직히 DP에서의 문자열 비교는 조금 꺼려진다. 속도 제한도 빡빡해질 뿐더러, 그냥 (…) 문자열이 싫다. 그런 면에서 WildCard는 어려운 문제라고 판단된다. 이 문제에서의 와일드 카드란 총 2개로 :

1. ? : 딱 하나의 문자 (char)만 치환해주는 녀석

2. * : length 1 이상의 문자 혹은 문자열을 치환해주는 녀석

이렇게 두 개의 와일드카드가 존재한다. 먼저 어떠한 경우에 true가 return 되는지 보자.

0. 공통 조건 : 비교하는 문자열의 끝에 도달하여야 한다.

1. 제일 마지막에 온게 ? 이거나 같은 문자 (예 : “apple”이거나 “appl?”) 인 경우.

2. 제일 마지막에 온 게 * 문자거나, * 문자의 연장인 경우 (예 : “ap*” 이거나 “appl*“)인 경우.

1번에 대해서는 누구도 불만이 없을 것이다. 다만 조금 까다로운게 2번 조건이다. *는 문자를 하나만 치환할수도, 1 < n 의 어떤 길이도 치환할 수 있기 때문이다. 일단 다른 조건부터 해결해보자.

3. 해답 코드

#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

int cache[101][101];

int solution(string target, string tmp, int a, int b, int tmpSize, int targetSize){
    int& ret = cache[a][b];
    if(ret != -1) return ret;
    //방문한 적이 있다면 바로 return
    while(a < targetSize && b < tmpSize && (target[a] == '?' || target[a] == tmp[b])) {
        ret = solution(target, tmp, a + 1, b + 1, tmpSize, targetSize);
        return ret;
    }
    // ? 와일드카드인경우
    if(a == targetSize){
        ret = (b == tmpSize);
        return ret;
    }
    // a끝에 도달한경우
    if(target[a] == '*'){
        if((b < tmpSize && solution(target, tmp, a, b+1, tmpSize, targetSize)) || (a < targetSize && (solution(target, tmp, a+1, b, tmpSize, targetSize)))){
            //b+1 = a는 계속 *로 머물고 b의 다음칸 대응 검사, a+1 = 이제 * 스킵하고 a의 다음 문자열 검사(사이즈 체크 필요)
            ret = 1;
            return ret;
        }
    }
    ret = 0;
    return ret;
}

int main(){
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        string target;
        cin >> target;
        int k;
        cin >> k;
        vector<string> ans;
        for(int j = 0; j < k; j++){
            memset(cache, -1, sizeof(cache));
            string tmp;
            cin >> tmp;
            if(solution(target, tmp, 0, 0, tmp.size(), target.size()) == 1){
                ans.push_back(tmp);
            }
        }
        sort(ans.begin(), ans.end());
        for (auto e : ans) {
            cout << e << "\n";
        }
    }
}

P.S. 8장에선 이 문제와 후에 나오는 Quantization 문제가 가장 어려웠다..


Source

[ comments ]