KMP字符串匹配

再次阅读算法这本书后,对字符串匹配KMP算法有了新的认识。

算法可以分为2部分:1.构建有限状态机转换矩阵,别被这个名字吓到,这个矩阵的作用就像是你在走迷宫时的一份地图,它可以告诉你下一步无论怎么走会发生什么情况。

                                  2.利用矩阵决定如何进行下一步的匹配。


先说说第二部分:假如你已经有了一份”地图“,该如何使用。

	//使用DFA进行查找
	public int search(String txt){
		int i ,j, N = txt.length(), M = pat.length();
		for(i=0, j=0; i<N && j<M; i++){
			j = dfa[txt.charAt(i)][j];			//更新回退状态
		}
		if(j == M) return i-M;
		else return N;
	}

这里txt为文本字符串,pat为待查询的模式字符串。利用指针来分别标识文本字符串和待搜索字符串的位置:其中i代表文本匹配到了第i个字符,j代表了待匹配字符串相对于i的位置。这里显示了kmp算法的核心思想:利用已经匹配的“已知文本”,来尽量减少没必要的匹配,让只想文本字符串的指针i永远不回退,而相对的j的进行回退。所以j在这里也代表待匹配的字符(pat)和已知文本字符的最大重叠长度。重叠的越多,pat就需要回退的越多。

再看看第一部分:“地图”的生成。

		int M = pat.length();
		int R = 256;
		dfa = new int[R][M];
		dfa[pat.charAt(0)][0] = 1;
		for(int X = 0, j=1; j<M; j++){
			for(int c=0; c<R; c++){
				dfa[c][j] = dfa[c][X]; //复制匹配失败状态
				dfa[pat.charAt(j)][j] = j+1; //匹配成功状态
				X = dfa[pat.charAt(j)][X]; 	//更新回退状态,用于下一次回退(当匹配到模式的第j个字符失败时,利用之前已经读取到了第1到j-1个字符,状态转换到第pat.charAt(j)行对应的状态——dfa[pat.charAt(j)][X])
			}
		}
这一步的思想是利用之前已经得到的状态来计算下一次匹配的状态。在每次构建新的状态时,利用回退状态X(匹配失败后的起点),将X状态复制到j状态,并修改j状态的匹配状态。最后更新X。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值