找出字符串中第一个匹配项的下标,重复的子字符串

76 阅读1分钟

找出字符串中第一个匹配项的下标

[题目](28. 找出字符串中第一个匹配项的下标)

思路

使用kmp算法,使用前缀表来记录对应位置,然后进行匹配 kmp算法主要用在字符串匹配上
难点主要是前缀表的计算以及通过前缀表匹配

代码实现

class Solution {
public:
    void getNext(int* next, const string & s) {
        int j = 0;
        next[0] = 0;
        for(int i = 1; i < s.size(); i++) {
            while (j > 0 && s[i] != s[j]) {
                j = next[j- 1];
            }
            if (s[i] == s[j]) {
                j++;
            }
            next[i] = j;
        }
    }
    
    int strStr(string haystack, string needle) {
        if (needle.size() == 0) {
            return 0;
        }
        int next[needle.size()];
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) {
            while (j > 0 && haystack[i] != needle[j]) {
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == needle.size()) {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }
};

重复的子字符串

[题目](459. 重复的子字符串)

思路

可以用两种方法:移动匹配和KMP

代码实现

// 移动匹配
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string t = s + s;
        // 掐头去尾
        t.erase(t.begin());
        t.erase(t.end() - 1);
        if (t.find(s) != std::string::npos) {
            return true;
        }
        return false;
    }
};

// kmp
class Solution {
public:
    void getNext(int* next, const string& s) {
        next[0] = 0;
        int j = 0;
        for(int i = 1; i < s.size(); i++) {
            while (j > 0 && s[i] != s[j]) {
                j = next[j - 1];
            }
            if (s[i] == s[j]) {
                j++;
            }
            next[i] =j;
        }
    }
    
    bool repeatedSubstringPattern(string s) {
        if (s.size() == 0) {
            return false;
        }
        int next[s.size()];
        getNext(next, s);
        int len = s.size();
        if (next[len - 1] != 0 && len % (len - (next[len - 1])) == 0) {
            return true;
        }
        return false;
    }
};