ABOUT ME

this is the signature project which made by KMS studio if you find error about my program, please give E-mail to tomskang@naver.com

Today
Yesterday
Total
  • 백준 1786번 찾기 (boj/1786.c)
    Life: research & education/PS 2024. 1. 18. 19:25

    KMP 알고리즘 문제입니다.

    #include <stdio.h>
    #include <string.h>
    #define MAX_N   1000002
    char T[MAX_N] = { 0, };
    char P[MAX_N] = { 0, };
    int pi[MAX_N] = { 0, };
    int res[MAX_N];
    int main(void){
        int lenT, lenP;
        int cur, loc, cnt;
        fgets(T, MAX_N, stdin);
        fgets(P, MAX_N, stdin);
        lenT=strlen(T); lenP=strlen(P);
        lenT--; lenP--; T[lenT]=P[lenP]=0;
        pi[0] = -1;
        for(int i=1;i<lenP;i++){
            pi[i]=-1;
            for(cur=i-1;cur!=-1;cur=pi[cur]){
                if(P[i] == P[pi[cur]+1]){ pi[i]=pi[cur]+1; break; } }
        }
        loc=-1; cnt=0;
        for(cur=0;cur<lenT;cur++){
            if(loc == -1){
                if(T[cur] == P[0]){ loc=cur; }
                else{ continue; } }
            if(T[cur] == P[cur-loc]){
                if(cur-loc==lenP-1){
                    res[cnt++] = loc+1;
                    loc = (pi[cur-loc]!=-1)?cur-pi[cur-loc]:-1;
                } else{ continue; } }
            else{ loc = (pi[cur-1-loc]!=-1)?(cur-1)-pi[cur-1-loc]:-1; cur--; }
        }
        printf("%d\n", cnt);
        for(int i=0;i<cnt;i++){ printf("%d ", res[i]); }
        return 0;
    }

     

    이 알고리즘은 작성할 시 주의할 점이 몇 가지 있습니다.

    • line 18: pi[idx]값이 항상 pi[idx-1]+1 또는 -1이 아니다. 즉, if(string[idx] == string[pi[idx-1]+1]) 에서 false가 뜨면 pi[idx-1]에서 재판단을 해줘야 한다. 당연히 시간복잡도는 O(M)이 아니다.
    • line 24: loc==-1인 상황에서, T[cur]=P[0]이 떳을 때 바로 continue를 때리면 안 됩니다. P의 길이가 1인 상황을 고려해야 하기 때문. 이 경우에는 loc==cur이 성립하기 때문에 line31의 if문에 들어가면 아웃바운드가 뜬다고 할 수 있는데, 조건에 따라 T[cur]==P[cur-loc]가 항상 성립할 것이기 때문에 아웃바운드는 뜨지 않습니다.
    • line 31: 만약, pi값이 -1이더라고, 현재 위치에서 재탐색을 한 번 해줘야 합니다. T=kaafg P=afg인 경우를 위해서입니다.
하면된다 學業報國