字符串匹配 KMP 算法 Java实现

标签: 字符串 匹配 kmp | 发表时间:2013-12-26 19:22 | 作者:
出处:http://www.iteye.com
字符串匹配过程中,如果使用蛮力算法,效率非常的差,在此介绍一种较为高效的匹配算法KMP算法。
其主要思想是从匹配的模版去分析,即去分析Pattern串的自身规律,进而去优化匹配的效率。例如字符串“ababcb”,明显看出是ab出现一组重复,若出现如下匹配模式:
        text:abababcb
     pattern: ababcb
此时发生错误,一般情况下会选择移动Pattern一个位置来继续,事实证明效果不佳。聪明的人一眼就看出来,下一步应该进行这样的匹配
          text:abababcb
       pattern:   ababcb
        通过一次移动两个位置便迅速完成匹配,而移动的位置大小也恰恰是ab这个重复串的大小,所以,匹配每次移动的位置一定和当前字符串的真前缀真后缀有关,根据科学家实验,移动的位置==最大相等真前后缀的长度,此时我们需要一个和模版一样长的数组去存放Pattern下次要移动的位置,我们称Nexd[]。
对于Parrern:"a  b a b c b" 这个模版来讲,
    它的next[]: -1 0 0 1 2 0
其中数字next[i]代表下次模版需要用Pattern[next[i]]去匹配text,而-1代表整个模版直接跳过当前字符。所以,算法的关键其实就是算出next[].
public class KMP
{
	public KMP()
	{
		
	}
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		String text = "ab abcb ababcb abab cb ababcb ababc ";
		String pattern ="ababcb";
		showList(getNext(pattern));
		kmpScan(text, getNext(pattern), pattern);
	}
	
	
	public static void kmpScan(String str, int[] next,String pattern)
	{
		int k =0;
		int j =0;
		int count =0;
		int index =0;
		//int[] index = new int[count];
		while(k<str.length())
		{
			
			if(j==-1&&k<str.length())
			{
				k++;
				j=0;
			}
			else if(str.charAt(k)==pattern.charAt(j))
			{	
				j++;
				k++;
			}
			else{
				j=next[j];
			}
			if(j==pattern.length())
			{
				index = k-j;
				j=0;
				k++;
				count++;
				System.out.println(index);//记录了字符出现的位置
			}
			
		}
		System.out.println(count);
	}
	public static int[] getNext(String pattern)
	{
		char[] pat = pattern.toCharArray();
		int[] next = new int[pattern.length()];
		next[0]=-1;
		next[1]=0;
		for (int i = 2; i < next.length; i++)
		{
			int k=next[i-1];
			while(k>=0)
			{	
				if(pat[k]==pat[i-1]) 
					break;
				k=next[k];
			}
			next[i]=k+1;
		}
		return next;
	}
	public static void showList(int next[])
	{
		for (int i = 0; i < next.length; i++)
		{
			System.out.printf("%d ",next[i]);
		}
		System.out.println();
	}
}


结果:
-1 0 0 1 2 0
8
23
2

结论:一种高效的算法,在英文匹配上比较出色,也可以将其用在byte匹配上~
      另一种更高效的算法BM,期待下一篇~

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [字符串 匹配 kmp] 推荐:

字符串匹配的KMP算法

- - 博客园_知识库
   字符串匹配是计算机的基本任务之一.   举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD".   许多算法可以完成这个任务, Knuth-Morris-Pratt算法(简称KMP)是最常用的之一. 它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth.

字符串匹配 KMP 算法 Java实现

- - ITeye博客
字符串匹配过程中,如果使用蛮力算法,效率非常的差,在此介绍一种较为高效的匹配算法KMP算法. 其主要思想是从匹配的模版去分析,即去分析Pattern串的自身规律,进而去优化匹配的效率. 例如字符串“ababcb”,明显看出是ab出现一组重复,若出现如下匹配模式:. 此时发生错误,一般情况下会选择移动Pattern一个位置来继续,事实证明效果不佳.

字符串匹配(BF,BM,Sunday,KMP算法解析)

- - CSDN博客综合推荐文章
字符串匹配一直是计算机领域热门的研究问题之一,多种算法层出不穷. 字符串匹配算法有着很强的实用价值,应用于信息搜索,拼写检查,生物信息学等多个领域. 今天介绍几种比较有名的算法:. BF(Brute Force)算法又称为暴力匹配算法,是普通模式匹配算法. 其算法思想很简单,从主串S的第pos个字符开始,和模式串T的第一个字符进行比较,若相等,则主串和模式串都后移一个字符继续比较;若不相同,则回溯到主串S的第pos+1个字符重新开始比较.

转载一篇单字符串匹配KMP算法最好理解的文章

- - 编程语言 - ITeye博客
字符串匹配是计算机的基本任务之一.   举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD".   许多算法可以完成这个任务,. Knuth-Morris-Pratt算法(简称KMP)是最常用的之一. 它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth.

KMP、AC自动机在字符串匹配类动态规划问题中的应用

- Sosi - C++博客-Mato is No.1
有一类动态规划(其中也包含递推)问题,要求满足一些限制条件的字符串,这些限制条件是“需要含有某个子串”或“不能含有某个子串”,那么KMP、AC自动机等就有大用了. 题意:字符集中有一些字符,给出每个字符的出现概率(它们的和保证为1),再给出一个子串B,求:任给一个长度为N的字符串A(只能包含字符集中的字符),使得S是A的子串的概率.

字符串匹配那些事(一)

- jiessie - 搜索技术博客-淘宝
本系列文章主要介绍几种常用的字符串比较算法,包括但不限于蛮力匹配算法,KMP算法,BM算法,Horspool算法,Sunday算法,fastsearch算法,KR算法等等. 本文主要介绍KMP算法和BM算法,它们分别是前缀匹配和后缀匹配的经典算法. 所谓前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从左到右;所谓后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右.

字符串匹配的Boyer-Moore算法

- - 阮一峰的网络日志
上一篇文章,我介绍了 KMP算法. 但是,它并不是效率最高的算法,实际采用并不多. 各种文本编辑器的"查找"功能(Ctrl+F),大多采用 Boyer-Moore算法. Boyer-Moore算法不仅效率高,而且构思巧妙,容易理解. 1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了这种算法.

最佳字符串匹配算法(Damerau-Levenshtein距离算法)的Java实现

- - Java - 编程语言 - ITeye博客
原文: http://www.javacodegeeks.com/2013/11/java-implementation-of-optimal-string-alignment.html.  It implements a few well known tricks to use less memory by only hanging on to two arrays instead of allocating a huge n x m table for the memoisation table.

JavaScript中的字符串操作

- - CSDN博客推荐文章
JavaScript中的字符串操作.    字符串在JavaScript中几乎无处不在,在你处理用户的输入数据的时候,在读取或设置DOM对象的属性时,在操作cookie时,当然还有更多.... JavaScript的核心部分提供了一组属性和方法用于通用的字符串操作,如分割字符串,改变字符串的大小写,操作子字符串等.