KMP

               1.简单字符串匹配

                  (1)问题描述

                            如给定字符串str1 = "abcaad" ,str2="",判断str1中是否包含str2

                  (2)思路

                            使用2个指针i、j,如果i,j指针指向字符相同,那么i++、j++;否则,j=0,i=i-j+1。

                  (3)代码

		String str1 = "cdbabcdabdsd";
		String str2 = "abcdabx";
		
		int i = 0;
		int j = 0;
		
		while(i<str1.length() && j<str2.length())
		{
			if(str1.charAt(i) == str2.charAt(j))
			{
				i++;
				j++;
			}
			else
			{
				i = i-j+1;
				j = 0;
			}
		}
		
		if(j==str2.length())
			System.out.println("find");
		else
			System.out.println("not find");

               2.kmp算法

                  (1)思想

                            由于简单匹配算法在匹配失败的时候,j=0,i每次都要回溯,从而造成时间复杂度过高。那么就需要使用一个数组,用来保存失配的时候,j指针回溯到何处,而i指针不回溯。那么算法就可以如下写:

		String str1 = "cdbabcdabdsd";
		String str2 = "abcdabx";
		
		int next[] = new int[str2.length()];
		
		getNext(str2,next);      //设置next数组的值
		int i = 0;
		int j = 0;
		while(i<str1.length() && j<str2.length())
		{
			if(j==-1 || str1.charAt(i)==str2.charAt(j) )
			{
				i++;
				j++;
			}
			else
				j = next[j];   //失配的时候i不变,j从next中找到需要回溯的位置
		}
		if(j==str2.length())
		{
			System.out.println(str1.substring(i-j, i));
		}
                            那么现在问题就是如何设置next数组的值?首先需要明确以下几点:

                            1)next[i]表示的是下标为i的字符失配,应该回溯到什么位置。开始时设置next[0] = -1,表示第一个字符就没匹配
                            2)next数组实际上是字符串和自身的匹配和其他串完全没有关系

                           现在讨论一般情况:

                           1>i == 0时,next[i] = -1。原因上面已经讲了

                           2>i != 0时:此时假设next[i] = k,即如果在str2第i个字符失配了,那么就回溯到第k个字符。

                              如果str2[i] == str2[k],那么next[++i] == ++k。

                              如果str2[i] != str2[k],那么 k = next[i]。

                              此处可以这么理解:虽然是str2自身的匹配,但是可以将str2[0-i]视为一个字符串s1 ,str2[0-k]视为另一个字符串s2,,那么由next[i] = k的就可以得出

str2[i-1]==str2[k-1],因为根据next定义可得在i失配可以回溯到k,那么如果str2[i] == str2[k], 就可以说在i+1失配的时候可以回溯到k+1(或者更简单的理解就是两个字符串第i和第k个字符相等,那么肯定就要比较下一个了)

                             如果str2[i] != str2[k],那么还是kmp,第二个字符串的k应该变为next[k]

                         

                  (2)代码

	private void getNext(String str, int[] next) 
	{
		next[0] = -1;
		int j = 0;
		int k = -1;
		while(j<(str.length()-1))     //因为next[str.length()-1]在前一轮的计算中会得出,所以只用到str.length()-1即可
		{
			if(k==-1 ||str.charAt(j)==str.charAt(k) )
			{
				j++;
				k++;
				next[j] = k;
			}
			else
				k = next[k];
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值