kmp

#include <iostream>
#include <string>
using namespace std;

// 构建KMP的next数组
void getNext(const string& t, int next[]) {
    int len = t.size();
    next[0] = -1;
    int j = 0, k = -1;
    while (j < len - 1) {
        if (k == -1 || t[j] == t[k]) {
            j++;
            k++;
            next[j] = k;
        } else {
            k = next[k];
        }
    }
}

// 利用KMP算法统计子串t在主串s中不重叠出现的次数,并显示匹配过程
int countKMPNonOverlap(const string& s, const string& t) {
    int sLen = s.size();
    int tLen = t.size();
    if (sLen < tLen) return 0;

    int next[tLen];
    getNext(t, next);

    int count = 0;
    int i = 0; // 主串指针
    while (i <= sLen - tLen) {
        int j = 0; // 子串指针
        // 显示当前匹配的主串起始位置(方便查看过程)
        cout << "当前主串起始位置: " << i << ",待匹配子串: " << t << endl;
        
        // KMP匹配过程
        while (j < tLen && s[i + j] == t[j]) {
            j++;
        }

        if (j == tLen) {
            // 匹配成功,计数+1,主串指针跳转子串长度(避免重叠)
            count++;
            cout << "匹配成功!位置: " << i << "~" << i + tLen - 1 << endl;
            i += tLen;
        } else {
            // 匹配失败,根据next数组调整主串指针
            if (next[j] == -1) {
                i++;
            } else {
                i += (j - next[j]);
            }
        }
    }
    return count;
}

int main() {
    string s = "aaabbdaabbd";
    string t = "aabbd";
    
    cout << "主串s: " << s << endl;
    cout << "子串t: " << t << endl;
    cout << "----------------匹配过程----------------" << endl;
    
    int result = countKMPNonOverlap(s, t);
    
    cout << "----------------匹配结果----------------" << endl;
    cout << "子串t在主串s中不重叠出现的次数: " << result << endl;

    return 0;
}

 

posted @ 2025-11-05 13:47  ouyeye  阅读(3)  评论(0)    收藏  举报