算法day26 找出字符串中第一个匹配的下标

题目描述

思路:kmp
这道题要找出字符串中第一个匹配的下标,那么我们首先应该解决的问题是如何正确的识别判断两个字符串之间是否匹配,那么这类问题KMP算法是最为有效的。我们可以通过采取KMP算法求出模式串的next数组,随后遍历主串与模式串进行比对,如果当前的元素不相等,我们就令模式串指针回退到对应的next数组元素所指示的位置上,若相同,我们就令模式串与主串同步向前,直到我们遍历完模式串,说明模式串匹配,我们此时返回其头部在主串对应的位置,若不匹配返回-1。

代码如下:

  void getnext(int *next,const string &s){
    int j = -1;   //采用了向前移动一位的前缀表
    next[0] = j;  //初始化next数组的首元素
    int len = s.size();
    for(int i = 1;i < len;i++ ){//i从1开始,要注意前缀表的求取过程是模式串自我前后缀比对的过程
        while(j>=0 && s[i] != s[j+1]){//这里要有j>=0的限制,否则会导致操作非法下标位置
            j = next[j];
        }
        if( s[i] == s[j+1]){
            j++;
        }
        next[i] = j;  //更新next数组的元素
    }
}
int strStr(string haystack, string needle) {
   int len1 = haystack.size();
   int len2 = needle.size();
   if(len2 == 0) return 0; //空字符串是任意非空字符串的子串
   vector<int> next(len2);
   getnext(&next[0],needle);
   int j = -1;
   for(int i =0;i<len1;i++){
    while(j>=0&&haystack[i]!=needle[j+1]){
        j = next[j];
    }
    if(haystack[i]==needle[j+1]){
        j++;
    }
    if(j == len2-1){
        return (i-len2+1);
    }
   }
   return -1;
}

时间复杂度:O(N+M)
空间复杂度:O(M(主要是neddle的长度带来的))

END

posted on 2025-05-11 10:44  sakura430  阅读(9)  评论(0)    收藏  举报