mycs

导航

 

模式匹配

  • KMP
    思想:
    当匹配到模式串p第j个元素 p0[j]!=p[i]
    可知p0(j-h,j-h+1,j-h+2...j-1)与p(i-h,i-h+1..i-1)相同
    由于根据模式串自身前后缀性质 显然当模式串滑动1,2...个元素时不可能与自身匹配成功 也就不能与目标串匹配成功
    故要找出最大滑动距离

image
缩小的范围可根据F数组迭代求解
image

int strStr(string haystack, string needle) {
	int n = haystack.size();
	int m = needle.size();
	vector <int> f(m);
	for (int i = 0; i < m - 1; i++) {
		f[i] = -1;
	}
	
	for (int i = 0; i < m - 1; i++)   //预处理F数组 找到最大滑动距离
	{
		int j = f[i];
		while (needle[i + 1] != needle[j + 1] && j >= 0) {//寻找相同前后缀范围
			j = f[j];   //缩小范围
		}
		if (needle[i + 1] == needle[j + 1]&&j>=0)f[i + 1] = j + 1;     //前缀为0~j+1    错误写法:f[i + 1] = f[j] + 1;
		else if(needle[i + 1] == needle[j + 1] && j == -1)f[i + 1] = 0;//前缀为第一个元素
		else f[i+1] = -1;                                              //无匹配前缀
	}
	int i = 0, j = 0;              //匹配开始
	                               //因i j均不倒退 故直接更新i j 而不是用辅助元素k i~i+k j~j+k
	while (i<n&&j<m) {
		if (needle[j] == haystack[i]) {
			 
			if (j == m - 1)return i-m+1;
			i = i + 1;
			j = j + 1;
		}
		else{
			 
				if (j == 0) i = i + 1;//若从模式串第一个元素就不匹配 则移动目标串指针
				else j = f[j-1] + 1;  
         /*
              错误写法:
               if (f[j] == -1) {
				j = 0;
               }
               else {
				j = f[j];
               }
         */
			 
		}
	}
	if (i < n) {
		return i-m;//
	}
	else{
		return -1;
	}
}
posted on 2025-09-24 20:25  Radarman108  阅读(2)  评论(0)    收藏  举报