串学习笔记

1、KMP算法

给出主串和模式串,求模式串在主串的位置

class Mystring {
    string s;
    int len;
    int* next;
public:
    Mystring(string s = "") {
        this->s = s;
        this->len = s.size();
        next = new int[len + 1];
        get_next();
    }

    // 构造next数组
    void get_next() {
        int i = 0;
        next[0] = -1;
        int j = -1;
        while (i < len - 1) {
            if (j == -1 || s[i] == s[j]) {
                ++i, ++j;
                next[i] = j;
                
            }
            else j = next[j];
        }
    }

    // KMP算法:在所给主串mains,查找模式串s是否在mains中,若在,则返回所在位置开头下标
    int KMP(string mains, int pos) {
        int i = pos, j = 0;
        while (i < mains.size() && j < len) {
            if (j == -1 || mains[i] == s[j]) {
                ++i, ++j;
            }
            else j = next[j];
        }
        if (j > len-1) return i - len ;
        else return -1;
    }

    // 展示next数组
    void show_next() {
        for (int i = 0; i < len; i++) {
            cout << next[i] << " ";
        }
        cout << endl;
    }
    
};

2、后缀数组求最长重复子串

求串的最长重复子串长度。例如:abcaefabcabc的最长重复子串是串abca,长度为4。

// 后缀数组求最长重复子串,若存在最长重复子串,则返回其长度
int work(string str) {
    vector s;  // 后缀数组

    for (int i = 0; i < str.size(); i++) {
        s.push_back(str.substr(i));
    }

    sort(s.begin(), s.end()); // 排序
    
    int maxlen = 0;
    for (int i = 0; i < str.size() - 1; i++) {
        for (int j = 1; j <= s[i].size() && j <= s[i + 1].size(); j++) {
            if (s[i].substr(0,j) == s[i + 1].substr(0,j)) {
                if (j > maxlen) {
                    maxlen = j;
                }
            }
            else break;
        }
    }
    if (maxlen != 0)
        return maxlen;
    else return -1;
}

你可能感兴趣的:(数据结构,学习,笔记,c++,数据结构)