首页 > 编程语言 > 详细

模式匹配KMP算法(Java)

时间:2015-03-25 17:23:19      阅读:197      评论:0      收藏:0      [点我收藏+]
/********查找匹配字符串**********/
//最原始、复杂度最高的做法
//返回childstr在mumstr中第pos个字符之后的位置,如果不存在,则返回0
public int FindStr(String mumstr, String childstr, int pos)
{
	//省去参数有效性判断
	
	if((childstr.length() > mumstr.length()) || (pos >= mumstr.length()))
		return 0;
	
	char[] mumarr = mumstr.toCharArray();
	char[] childarr = childstr.toCharArray();
	int i = pos;
	int j = 0;
	
	while((i < mumarr.length) && ( j < childarr.length))
	{
		//如果匹配情况
		if( mumarr[i] == childarr[j])
		{
			++i;
			++j;
		}
		//如果不匹配,则从头开始匹配
		else
		{
			i = i - j + 1;
			j = 0;
		}
	}
	
	//判断是否匹配成功,如果匹配成功,则跳出循环条件应该为 j = childarr.length情况
	if( j >= childarr.length)
	{
		return i - j;
	}
	return 0;
}

/**************KMP算法*****************/
//KMP算法主要思想在于比较指针不回溯,通过计算next[j],将匹配指针回溯到next[j]位置与i位置的主字符串进行比较

//next[j]计算函数
/*初始化next[1] = 0;(注意实现时要注意算法中str的位置与算法中位置的区别)
  且注意计算next[j]时,比较的是一直到j-1的字符串
  next[j]计算共分为两种情况:记next[j] = k; 
  1.str[j] = str[k],则next[j + 1] = next[j] + 1 = k + 1;
  2.若不等,则把比较想象成模式和主字符串都是childstr的模式匹配。则应该让str[j] 和str[next[k]]进行比较(这里记next[j] = k);
    1) 相等,则next[j + 1] = next[k] + 1 = k' + 1;
	2) 不相等,则继续令next[k] = k',将str[j]与str[k' + 1]作比较;
*/
private int[] getNext(String childstr)
{
	//参数初始化
	int length = childstr.length();
	char[] childarr = childstr.toCharArray();
	int next[] = new int[length];
	next[0] = -1;//标志位字符串初始位
	int i = 0;
	int j = -1;
	
	while ( i < length - 1)
	{
		if( i == 0 || j == -1 ||childarr[i] == childarr[j])//注意不能忘记j=-1的初始情况
		{
			next[++i] = ++j;
		}
		else
		{
			j = next[j]; 
		}
	}	
	return next;
}
/*******************KMP算法********************/
public int IndexKMP(String mumstr, String childstr, int pos)
{
	if((childstr.length() > mumstr.length()) || (pos >= mumstr.length()))
		return 0;
	
	char[] mumarr = mumstr.toCharArray();
	char[] childarr = childstr.toCharArray();
	int i = pos;
	int j = 0;
	int[] next = getNext(childstr);
	
	while ((i < mumarr.length)&&(j < childarr.length))
	{
		if(j == -1 || mumarr[i] == childarr[j])//注意还要加上j=-1的最初始化情况
		{
			++i;
			++j;
		}
		else
		{
			//i不变,j变为next[j]
			j = next[j];
		}
	}		
	
	if ( j >= childarr.length)
	{
		return i - j;
	}
	return 0;	
}

public static void main(String[] args) {
	StrMatch strMatch = new StrMatch();
	String aString = "ababccddefgabcdefghij";
	String bString = "ababccddefg";
	
	System.out.println(strMatch.IndexKMP(aString, bString, 3));

}


/********改进的nextval算法********/
/*当遇到      a  a  a  a  b  情况
     next[j]  0  1  2  3  4
    nextval[j]0  0  0  0  1
	
	即当比较到b时不等,回溯到next[4] = 3位置,比较a,仍不等则继续前移next[3] = 2;仍然是比较a,结果仍然是不等
	故希望能够直接回溯至第一个a位置;
	
	则改进算法中,next[j] = k; 若str[j] = str[k],则应和str[next[k]]进行比较,若str[j] = str[next[k]],则继续前移,
	直至str[j]与其不相等;则next[j] = next[k],直至不相等的初始情况

*/

private int[] nextval(String childstr)
{
	//参数初始化
	int length = childstr.length();
	char[] childarr = childstr.toCharArray();
	int next[] = new int[length];
	next[0] = -1;//标志位字符串初始位
	int i = 0;
	int j = -1;
	
	while ( i < length - 1)
	{
		if( i == 0 || j == -1 ||childarr[i] == childarr[j])//注意不能忘记j=-1的初始情况
		{
			++i;
			++j;
			//再多一层对相等元素的判断
			if(childarr[i] == childarr[j])//对应next[j] = next[k]情况
			{
				next[i] = next[j];
			}
			else
			{
				next[i] = j;
			}
		}
		else
		{
			j = next[j]; 
		}
	}	
	return next;
}



模式匹配KMP算法(Java)

原文:http://blog.csdn.net/woliuyunyicai/article/details/44622573

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!