zoukankan      html  css  js  c++  java
  • KMP算法/POJ3461(求匹配字符子串的个数)

    1.Next数组

    next[j]={

    j=1时,0

    j!=1时,最大子串长度+1,即P1P2….Pk-1==Pj-k+1….Pj-1,1<k<j,(看来j=2时是没有最大子串的,因此next[2]一定为1)

    其它情况,1

    }

    next[j]=0说明模式串与匹配串都要后移一位

    next[j]!=0说明匹配串的当前字符与next[j]匹配

    next数组的下标从1开始,因此我们在模式串(T)的前面添加一个字符‘#’,初始化next[1]=0

    求每个next[j](j>1)时实际上利用到上next[j-1]的值

    如求next[5]时,则查看next[4]的值,如果T[4]=T[next[4]],则next[5]=next[4]+1

    如果T[4]!=T[next[4]],T[4]再与next[T[next[4]]]比,如果相等,则next[5]=next[T[next[4]]]+1,如此继续,如果它的next值为0,则跳到其它情况

    因此,标准算法如下:

    void get_next()
    {
    	unsigned int length = strlen(t);
    	next[0]=0;
    	next[1]=0;
    	unsigned int i=1,j=next[1];
    	while(i<length-1){
    		if(j==0){
    			i++;
    			j=1;
    			next[i]=1;
    			continue;
    		}
    		if(t[i]==t[j]){
    				i++;
    				j++;
    				next[i]=j;
    		}else 
    			j = next[j];
    	}
    	
    }

    这段代码优化一下:

    scanf("%s",t+1);

    t[0]=’#’;

    void get_next()
    {
    	unsigned int length = strlen(t);
    	//next[0]=0;
    	next[1]=0;
    	unsigned int i=1,j=next[1];
    	while(i<length-1){
    		
    		if(j==0||t[i]==t[j]){
    				i++;
    				j++;
    				next[i]=j;
    		}else 
    			j = next[j];
    	}
    	
    }

    对于POJ3461,next数组要多求一位

    要求:求出上串在下串中出现的次数

    Sample Input
    3
    BAPC
    BAPC
    AZA
    AZAZAZA
    VERDI
    AVERDXIVYERDIAN

    Sample Output
    1
    3
    0

    #include <iostream>
    using namespace std;
    #define MAX 1000003
    unsigned int next[MAX];
    char s[MAX];
    char t[MAX];
    void get_next()
    {
    	unsigned int length = strlen(t);
    	next[0]=0;
    	next[1]=0;
    	unsigned int i=1,j=next[1];
    	while(i<length){
    		
    		if(j==0||t[i]==t[j]){
    				i++;
    				j++;
    				next[i]=j;
    		}else 
    			j = next[j];
    	}
    	
    }
    unsigned int kmp(){
    	unsigned int length = strlen(s)-1;
    	unsigned int matLen = strlen(t)-1;
    	if(length<matLen)return 0;
    	unsigned int i=1,j=1,count = 0;
    	while(i<=length){
    		
    		if(j==0||s[i]==t[j]){
    			i++;
    			j++;
    			
    		}
    		else j = next[j];
    		if(j==matLen+1){
    			count++;
    			j = next[j]; 
    			}
    
    	}
    	return count;
    }
    
    int main()
    {
    	freopen("i://in.txt","r",stdin);
    	int count;
    	scanf("%d",&count);
    	t[0]='#';
    	s[0]='#';
    	for(int i=0;i<count;i++){
    	scanf("%s",t+1);
    	scanf("%s",s+1);
    	get_next();
    	printf("%d\n",kmp());
    	
    	}
    	return 0;
    }
  • 相关阅读:
    validation 参数效验框架
    小酌一下:Maven
    小酌一下:git 常用命令
    小酌一下:anaconda 基本操作
    小酌一下:Win10 解决fetch_20newsgroups下载速度巨慢
    学习笔记:Python3 异常处理
    学习笔记:Python3 面向对象
    学习笔记:Python3 函数式编程
    学习笔记:Python3 函数
    学习笔记:Python3 高级特性
  • 原文地址:https://www.cnblogs.com/yangyh/p/2061913.html
Copyright © 2011-2022 走看看