[Title] every day LeetCode 0028. string matching


Open Source Address: https://github.com/jiauzhang/algorithms


Title Description

*  https://leetcode-cn.com/problems/implement-strstr
*   给定一个 haystack 字符串和一个 needle 字符串,
*   在 haystack 字符串中找出 needle 字符串出现的第一个位置(从0开始)。
*   如果不存在,则返回  -1。
* 
* 示例 1:
*     输入: haystack = "hello", needle = "ll"
*     输出: 2
* 
* 示例 2:
*     输入: haystack = "aaaaa", needle = "bba"
*     输出: -1
* 
* 说明:
*     当 needle 是空字符串时,我们应当返回 1.

Problem-solving ideas

  1. The easiest way is to match the violence, not described here
  2. The classic solution is to KMP matching algorithm, the core of the KMP algorithm
    is to calculate the greatest common prefix and suffix, produces an array of next
    change the thinking to understand the array, which in fact is an indication of template string
    have the same maximum substring template, so you can skip those that do not exist
    substring same template, templates to accelerate the speed of migration, without having to determine
    violence as matching method, every failure need to re-start match, which is the
    reason for the faster KMP algorithm , the algorithm complexity is O (M + N)
  3. And also some of the KMP algorithm similar, such as BM algorithm, Sunday algorithm

Sample Code

class Solution {
public:
    int strStr(string haystack, string needle) {
        if (!needle.size())
            return 0;
        
        if (!haystack.size())
            return -1;
        
        vector<int> next;
        get_next(needle, next);

        int i = 0, j = 0;
        /* 
          这里要格外注意,调试了很久才找到错误原因
          必须对 string::size() 函数的返回值进行强制类型转换
        */
        while (i < (int)haystack.size() && j < (int)needle.size()) {
            if ((j == -1) || (haystack[i] == needle[j])) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }

        if (j == needle.size()) {
            return i - j;
        } else {
            return -1;
        }
    }
    
    void get_next(string &tmpl, vector<int> &next) {
        next.resize(tmpl.size());
        next[0] = -1;

        int k = -1;
        int j = 0;
        while (j < next.size() - 1)
        {
            if (k == -1 || tmpl[j] == tmpl[k]) 
            {
                k++;
                j++;
                if (tmpl[j] != tmpl[k])
                    next[j] = k;
                else
                    next[j] = next[k];
            }
            else 
            {
                k = next[k];
            }
        }
    }
};

Guess you like

Origin www.cnblogs.com/jiau/p/11655052.html