KMP算法

传统的字符串比较需要不停的回溯,重复比较,但是已经比较并匹配的字符其实是已知的就是待匹配字符串自身的字符,如此可以根据这些已知信息减少回溯的字符。整个字符串的匹配只需要不停匹配下一个字符。那么待匹配字符串每次回溯的位置则根据自身决定(根据前面已经匹配的字符串)并不需要每次回溯的开头的位置。既然是根据自身,就可以先计算出每个字符的回溯位置,即next数组。next数组即表示从第二个字符开始到当前字符位置的子字符串和其自身(从第一个字符开始的子字符串)的匹配的字符个数。比如abcab  的next数组(构建next数组的复杂度是o(m)  m是待匹配字符串的长度)

abcab
00(a,b不匹配)0(a,c不匹配)1(a,a匹配)2(ab,ab匹配)

 

class StringPattern {
public:
	int kmp_search(string& str, string& find_str, vector<int>& next){
		int n = str.size();
		int j = 0;
		int i = 0;
		while (i<n){
			if (str[i] == find_str[j]){
				++i;
				++j;
				if (j == find_str.size())return i - find_str.size();
			}
			else{
				if (j > 0)
					j = next[j - 1];
				else
					i++;

			}
		}
		return -1;

	}
	void nextstep(string str, vector<int>& next){
		int n = str.size();
		if (n <= 0)return;
		int i = 0;
		int j = 1;
		next[0] = 0;
		while (j < n){
			if (str[j] == str[i]){

				i++;

				next[j] = i;


			}
			else{
				next[j] = 0;
				i = 0;

			}
			j++;
		}
	}
	int findAppearance(string A, int lena, string B, int lenb) {
		
		if (lena <= 0 || lenb <= 0 || lena != A.size() || lenb != B.size())return -1;
		if (lenb>lena)return -1;
		vector<int> next(lenb,0);
		nextstep(B, next);
		return kmp_search(A, B, next);
	}
};
int main(){
	StringPattern s;
	string str = "bc";	
	string str1 = "acbc";
	cout << s.findAppearance(str1,4,str,2);
	
	return 0;


}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值