kmp求助
查看原帖
kmp求助
754438
Maxwell1楼主2024/8/7 15:38

求帮忙

//求字符串Q里是否存在字符串T(的位置)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 2;
int prefix[MAXN];

void prefix_table(string T,int lenn) {   //制作公共前后缀表
    prefix[0] = 0;
    int len = 0;
    int i = 1;
    while(i < lenn) {
        if(T[i] == T[len]) {
            ++len;
            prefix[i] = len;
            i++;
        } else {
            if(len != 0) {
                len = prefix[len - 1];
            } else {
                prefix[i++] = 0;
            }
        }
    }
}

void move_right(string T, int lenn) {             //把prefix数组向右移动一格,第0格为-1
    for(int i = lenn; i > 0; --i) {
        prefix[i] = prefix[i - 1];
    }
    prefix[0] = -1;
}

int ans[MAXN], cnt = 0;

void kmp_search(string T, string Q, int lenn, int lenq) {
    int i = 0, j = 0; // i是查询字符串Q的标记,j是被查询字符串T的标记
    memset(ans, -1, sizeof(ans));
    while(i < lenq) {
        if(j == lenn) {
            cout << i - lenn + 1 << endl;
            i = i - lenn + 2;
            j = 0;
        }
        if(Q[i] == T[j]) {
            i++;
            j++;
        } else {
            if(j > 0)
                j = prefix[j];
            else
                i++;
        }
        //cout << i << " ";
    }
    if(j == lenn) {
        cout << i - lenn + 1 << endl;
        i = i - lenn + 2;
        j = 0;
    }
}

string T, Q;
int main() {
    cin >> Q >> T;
    int lenn = T.length();
    int lenq = Q.length();
    prefix_table(T, lenn);
    move_right(T, lenn);
    kmp_search(T, Q, lenn, lenq);/*
    for(int i = 0; i < cnt; ++i) {
        cout << ans[i] << endl;
    }
    cout << endl;*/
    for(int i = 1; i <= lenn; ++i) {
        cout << prefix[i] <<" ";
    }
    return 0;
}

本题我是有两个点没过,70分。

kmp_search()函数的while循环中,在搜索到当前答案后,是否要把j归0呢?我因此纠结了很久。

但是,我尴尬地发现,如果不加就会RE,加了就会WA,而且出错的都是Subtask #2的第12个和第14个点。

解决不了,故求教大佬们,感激不尽。

2024/8/7 15:38
加载中...