공부기록

Wildcard 본문

코테/종만북

Wildcard

코타쿠 2021. 8. 19. 23:06

문제

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

코드

#include <iostream>
#include <string>

using namespace std;

bool match(const string& w, const string& s) {
    int pos = 0;
    while (pos < w.size() && pos < s.size() && (w[pos] == '?' || w[pos] == s[pos]))
        pos++;
    if (pos == w.size())
        return w.size() == s.size();
    if (w[pos] == '*') {
        for (int skip = 0; pos + skip <= s.size(); skip++)
            if (match(w.substr(pos + 1), s.substr(pos + skip)))
                return true;
    }
    return false;

}

int cache[101][101];

string W, S;

int matchMemo(int w, int s) {
    int& ret = cache[w][s];
    if (ret != -1)
        return ret;

    while (w < W.size() && s < S.size() && (W[w] == '?' || W[w] == S[s])) {
        w++;
        s++;
    }
    if (w == W.size())
        return W.size() == S.size();
    if (W[w] == '*') {
        if(matchMemo(w+1,s) || (s  < S.size() && matchMemo(w, s+1)))
            return ret;

    }
    return ret = 0;
}

피드백

  • 일단 못풀었다. 처음엔 뭔가 DP처럼 풀고싶어서 w의 첫번째 자리를 s의 몇 번째 자리부터 매칭시키는 걸 해봤는데 실패
  • 책의 알고리즘은 다음과 같다.
    • 와일드패턴과 문자열이 서로 매칭될수 있을 때 까지 오프셋을 움직인다.
    • 멈췄을 때 와일드 패턴의 끝인지 판단한다.
    • 끝이라면 문자열도 끝인지 판단한다. 문자열도 끝이라면 정답이고, 그렇지 않다면 더 확인해야 한다.
    • 와일드패턴의 와일드 문자에 도달했는지 확인한다.
    • 그렇다면 문자열의 현재 문자를 와일드 문자에 먹일지, 와일드 문자 다음의 패턴으로 이을지 두 가지 경우에 대해 진행해야된다.
    • 둘중 하나라도 정답이 나오면 정답이기에, 위와 같이 코드를 짜서 ret에 반영시켜 리턴한다.
    • 위의 경우에 아무것도 해당되지 않는다면 그냥 문자가 틀린 것이다. 오답인 0을 리턴한다.
  • 책의 풀이는 먼저 완전탐색으로 구현하고, 중복되는 케이스를 메모이제이션 한 풀이를 보였다.
    • 이 풀이는 완전탐색을 먼저 구현하고 중복이 될 수 있는 것을 찾으면 dp를 구현할 수 있기 때문에 꼭 생각해두자
    • 물론, 완전탐색 방법을 먼저 생각해야 한다... (이 문제는 생각을 못함)

'코테 > 종만북' 카테고리의 다른 글

울타리 잘라내기  (0) 2021.07.08
Synchronizing Clocks  (0) 2021.07.05