본문 바로가기
자료구조와 알고리즘/알고리즘

9996

by oncerun 2023. 7. 4.
반응형

 

문제요약

 

패턴은 알파벳 소문자 여러 개와 별표(* : 아스키값 42) 하나로 이루어진 문자열이다.

*는 정규표현식의 *와 동일하게 동작한다. 0개 혹은 하나 이상이다.

주어진 패턴에 파일 이름의 일치 여부를 판단해라. 

 

 

입력

 

문자열 길이는 100을 넘지 않는다.

별표는 문자열의 시작과 끝에 있지 않는다.

 

출력

 

입력으로 주어진 i번째 파일 이름이 패턴과 일치하면 "DA", 일치하지 않으면 "NE"를 출력한다.

 

풀이

 

정규표현식의 특정 표현을 만들어보는 유익한 경험이라 생각하자.

 

 

1차 시도 Failed (이 왜 틀?)

#include <bits/stdc++.h>

using namespace std;


int n;
string pattern;
vector<string> result;


int main() {
    cin >> n;
    cin >> pattern;
    
    char wildcard = '*';
    size_t wildcardIdx =pattern.find(wildcard);

    string front = pattern.substr(0, wildcardIdx);
    string back = pattern.substr(wildcardIdx + 1);

    for (int i = 0; i < n; i++) {
        string input;
        cin >> input;
        bool match = true;

        for(int j=0; j<front.size(); j++){
            if(front[j] != input[j]){
                match = false;
                break;
            }
        }

        for(int k = 1; k <= back.size(); k++){
            if(back[back.size() - k] != input[input.size() - k]){
                match = false;
                break;
            }
        }

        if(match){
            result.emplace_back("DA");
        }else{
            result.emplace_back("NE");
        }
    }

    for (auto s: result) {
        cout << s << '\n';
    }


    return 0;
}

 

2차 시도 성공

#include <bits/stdc++.h>

using namespace std;



int main() {
    int n;
    string pattern;
    vector<string> result;

    cin >> n;
    cin >> pattern;
    
    char wildcard = '*';
    size_t wildcardIdx = pattern.find(wildcard);

    string front = pattern.substr(0, wildcardIdx);
    string back = pattern.substr(wildcardIdx + 1);

    for (int i = 0; i < n; i++) {
        string input;
        cin >> input;
        bool match = true;
        if (front.size() + back.size() > input.size()) {
            cout << "NE\n";
            continue;
        }

        for(int j=0; j<front.size(); j++){
            if(front[j] != input[j]){
                match = false;
                break;
            }
        }

        if(!match) {
            cout << "NE\n";
            continue;
        }

        for(int k = 1; k <= back.size(); k++){
            if(back[back.size() - k] != input[input.size() - k]){
                match = false;
                break;
            }
        }

        if(match){
            cout << "DA\n";
        }else{
            cout << "NE\n";
        }
    }
    return 0;
}

 

이 문제는 접두사, 접미사의 일치만 생각할 수 있는데, 실제 반례를 생각해 내야 하는 문제였다.

 

ab*ab와 같은 패턴이 있는 경우 ab라는 문자열이 들어오면 접두사, 접미사가 동일하기 때문에 반례조건이 없다면 일치로 처리되고, 이는 틀린 오답을 출력하게 된다.

 

그래서 이를 위한 최소, 최대 조건을 설정해줘야 하는 문제였다.

 

최종 정리 코드

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    string pattern;
    vector<string> result;

    cin >> n;
    cin >> pattern;
    
    char wildcard = '*';
    size_t wildcardIdx = pattern.find(wildcard);

    string front = pattern.substr(0, wildcardIdx);
    string back = pattern.substr(wildcardIdx + 1);

    for (int i = 0; i < n; i++) {
        string input;
        cin >> input;
        if (front.size() + back.size() > input.size()) {
            cout << "NE\n";
            continue;
        }
        if(front == input.substr(0, front.size()) && back == input.substr(input.size() - back.size())) cout << "DA" << '\n';
        else cout << "NE" << '\n';

    }
    return 0;
}
반응형

'자료구조와 알고리즘 > 알고리즘' 카테고리의 다른 글

1620  (0) 2023.07.06
2559  (0) 2023.07.06
ROT13(11655)  (0) 2023.07.02
농구 경기(1159)  (0) 2023.07.02
Palindrome  (0) 2023.07.02

댓글