zoukankan      html  css  js  c++  java
  • 算法思想

    1、KMP算法

    设有两串字符,第一串为主串,第二串为副串,求副串在主串的匹配index头。

    主要是求next数组,感性认识是副串的前后缀匹配程度:

           - "A"的前缀和后缀都为空集,共有元素的长度为0;

      - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;

      - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

      - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

      - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

      - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

      - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

    class Solution {
    public:
        int strStr(string haystack, string needle) {
            int m = haystack.length(), n = needle.length();
            if (!n) {
                return 0;
            }
            vector<int> lps = kmpProcess(needle);
            for (int i = 0, j = 0; i < m; ) {
                if (haystack[i] == needle[j]) { 
                    i++;
                    j++;
                }
                if (j == n) {
                    return i - j;
                }
                if ((i < m) && (haystack[i] != needle[j])) {
                    if (j) {
                        j = lps[j - 1];
                    }
                    else {
                        i++;
                    }
                }
            }
            return -1;
        }
    private:
        vector<int> kmpProcess(string& needle) {
            int n = needle.length();
            vector<int> lps(n, 0);
            for (int i = 1, len = 0; i < n; ) {
                if (needle[i] == needle[len]) {
                    lps[i++] = ++len;
                } else if (len) {
                    len = lps[len - 1];
                } else {
                    lps[i++] = 0;
                }
            }
            return lps;
        }
    };
    class Solution {
    public:
        vector<int> GetNext(string P)
        {
            vector<int> next(P.size(), 0);
            int p_len = P.size();
            int i = 0;   // P 的下标
            int j = -1;
            next[0] = -1;
    
            while (i < p_len - 1)
            {
                if (j == -1 || P[i] == P[j])
                {
                    i++;
                    j++;
                    next[i] = j;
                }
                else
                    j = next[j];
            }
            vector<int> v2(next.size(), 0);
            copy(next.begin(), next.end(), v2.begin());
            return v2;
        }
    
        //在 S 中找到 P 第一次出现的位置 /
        int strStr(string S, string P)
        {
    
    
    
            int i = 0;  // S 的下标
            int j = 0;  // P 的下标
            int s_len = S.size();
            int p_len = P.size();
            if (!p_len) return 0;
    
            vector<int> next = GetNext(P);
    
    
            while (i < s_len && j < p_len)
            {
                if (j == -1 || S[i] == P[j])  // P 的第一个字符不匹配或 S[i] == P[j]
                {
                    i++;
                    j++;
                }
                else
                    j = next[j];  // 当前字符匹配失败,进行跳转
            }
    
            if (j == p_len)  // 匹配成功
                return i - j;
    
            return -1;
        }
    };
    //优化版
    
    /* P 为模式串,下标从 0 开始 */
    void GetNextval(string P, int nextval[])
    {
        int p_len = P.size();
        int i = 0;   // P 的下标
        int j = -1;  
        nextval[0] = -1;
    
        while (i < p_len - 1)
        {
            if (j == -1 || P[i] == P[j])
            {
                i++;
                j++;
              
                if (P[i] != P[j])
                    nextval[i] = j;
                else
                    nextval[i] = nextval[j];  // 既然相同就继续往前找真前缀
            }
            else
                j = nextval[j];
        }
    }
  • 相关阅读:
    Arduino-原理图标识
    python-垃圾回收机制
    利用浮力测密度
    sys模块-与python解释器交互的模块
    第十一章第二节 功率
    第十一章第一节 功
    类-描述器-把类对象方法转变为属性方式
    H5浏览器播放RTMP直播流
    如何查看某个端口被谁占用
    OBS第三方推流直播教程
  • 原文地址:https://www.cnblogs.com/hotsnow/p/9581672.html
Copyright © 2011-2022 走看看