Leetcode Algorithm #28 Implement strStr()

Leetcode Algorithm #28 Implement strStr()

topic content

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "hello", needle = "ll"
Output: 2

Example 2:

Input: haystack = "aaaaa", needle = "bba"
Output: -1

problem solving

Generally, the first thing that comes to mind when seeing string matching is the most classic KMP algorithm, but it has been a long time since the last time the KMP algorithm was used. It is difficult to deduce it without checking it, so I will review it here. See Knuth–Morris–Pratt (KMP) Pattern Matching (Substring search)

The first is to perform a generation prefixpreprocessing on the search target, such as the search string p, the character whose index is ithe character, the corresponding prefixvalue should be 0~i-1the longest string of the prefix and suffix at the same time (called such a string as the prefix and suffix) . suffix string ) end position. After reviewing this definition, I have a good understanding of the purpose of looping forward in KMP while, which is to constantly check whether there is such a prefix and suffix string, which satisfies the character after the prefix is ​​the same as the current character to be matched. If If there is no identical, the flag bit will go back to the front.

Assuming a string, now the strings of 0-5 and 10-15 constitute a prefix and suffix string, now the character X at the test position 16, the 6th character is not equal to X, so we perform forward tracing, find a more Small suffix strings, such as 0-3 and 12-15, are a suffix string. At this time, the 4th character is the same as X, so pos[16] = 4.

class Solution {
public:
    int strStr(string haystack, string needle) {
        init(needle);
        int cur1 = 0, cur2 = -1, len = haystack.length(), need = needle.length();
        if (need == 0)
            return 0;
        for (; cur1 < len; ++cur1) {
            while (cur2 > -1 && needle[cur2+1] != haystack[cur1])
                cur2 = pos[cur2];
            if (needle[cur2+1] == haystack[cur1])
                ++cur2;
            if (cur2 == need - 1)
                return cur1 - need + 1;
        }
        return -1;
    }
private:
    int pos[50000];
    void init(string needle) {
        // cur1为用于设置pos值的前方指针,cur2为用于测试最长前后缀字符串的指针
        int len = needle.length(), cur1 = 1, cur2 = -1;
        pos[0] = -1;
        for (; cur1 < len; ++cur1) {
            // 不满足前缀后字符与测试字符相同和未回到原位时,前溯测试更短的前后缀字符串
            while (cur2 > -1 && needle[cur2+1] != needle[cur1])
                cur2 = pos[cur2];
            if (needle[cur2+1] == needle[cur1])
                ++cur2;
            pos[cur1] = cur2;
        }
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324604949&siteId=291194637