zoukankan      html  css  js  c++  java
  • HDU 1686 & KMP

    题意:

      求模板在匹配串所有子串中出现次数.

    SOL:

      本题与普通kmp有一点不同,因为待匹配串中的模板串可能相互包含.

      我们考虑正常的kmp是在怎么做的

         i = 1 2 3 4 5 6 7 8 9 ……
        A = a b a b a b a a b a b …
        B = a b a b a c b
         j = 1 2 3 4 5 6 7

       i=j=6时两个字符串不同了,那么j要减小到上一个匹配的地方.

      当匹配完了呢?

      比如 

      i = 1 2 3 4 5 6

        A= a z a z a

        B= a z a

      当A,B在3处匹配后,


      真是个大傻逼!...原来我一直WA的原因是因为多组数据存的时候数组也没有清除多余的元素,然后在最后判断的时候会出现问题....

    void kmp(){

       int j=0,ans=0;

       FORP(i,1,m){

           while (j && b[i]!=a[j+1]) j=p[j];

         if (b[i]==a[j+1]) j++;

         if (j==n) ans++;//,j=p[j];

       }

       printf("%d ",ans);

    }

       上面的while能完全实现匹配完把j变成p[j]的作用....

      对于网上blog蛊惑的改动匹配时指针的移动....根本不需要啊...

      

    /*==========================================================================
    # Last modified: 2016-03-01 19:22
    # Filename: b.cpp
    # Description: 
    ==========================================================================*/
    #define me AcrossTheSky 
    #include <cstdio> 
    #include <cmath> 
    #include <ctime> 
    #include <string> 
    #include <cstring> 
    #include <cstdlib> 
    #include <iostream> 
    #include <algorithm> 
      
    #include <set> 
    #include <map> 
    #include <stack> 
    #include <queue> 
    #include <vector> 
     
    #define lowbit(x) (x)&(-x) 
    #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
    #define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
    #define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
    #define ls(a,b) (((a)+(b)) << 1) 
    #define rs(a,b) (((a)+(b)) >> 1) 
    #define getlc(a) ch[(a)][0] 
    #define getrc(a) ch[(a)][1] 
     
    #define maxn 1100000 
    #define maxm 100000 
    #define pi 3.1415926535898 
    #define _e 2.718281828459 
    #define INF 1070000000 
    using namespace std; 
    typedef long long ll; 
    typedef unsigned long long ull; 
     
    template<class T> inline 
    void read(T& num) { 
        bool start=false,neg=false; 
        char c; 
        num=0; 
        while((c=getchar())!=EOF) { 
            if(c=='-') start=neg=true; 
            else if(c>='0' && c<='9') { 
                start=true; 
                num=num*10+c-'0'; 
            } else if(start) break; 
        } 
        if(neg) num=-num; 
    } 
    /*==================split line==================*/ 
    char a[maxn],b[maxn],temp[maxn];
    int p[maxn];
    int n,m;
    void getfail(){
    	p[1]=0; int j=0;
    	FORP(i,2,n){
    		while (j && a[i]!=a[j+1]) j=p[j];
    		if (a[i]==a[j+1]) j++;
    		p[i]=j;
    	}
    }
    void kmp(){
    	int j=0,ans=0;
    	FORP(i,1,m){
    		while (j && b[i]!=a[j+1]) j=p[j];
    		if (b[i]==a[j+1]) j++; 
    		if (j==n) ans++;//,j=p[j];
    	}
    	printf("%d
    ",ans);
    }
    int main(){
    	int cas; read(cas);
    	while (cas--){
    		scanf("%s",temp);n=strlen(temp); FORP(i,0,n-1) a[i+1]=temp[i];
    		a[n+1]='~';
    		scanf("%s",temp);m=strlen(temp); FORP(i,0,m-1) b[i+1]=temp[i];
    		b[m+1]='*';
    		getfail();
    		kmp();
    	}
    } 
    

      

    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    使用Spring RestTemplate 发送 List<MultipartFile>,上传多个文件
    二分查找的非递归实现
    图的深度优先遍历和广度优先遍历
    快速排序学习
    szwl面试记录
    Mycat对Mysql进行分库分表
    Java使用队列解决约瑟夫问题
    pa_hzzx面试总结
    Linux pam 后门纪录root用户密码以及自己设置root密码登录root
    JSP线程安全
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5233497.html
Copyright © 2011-2022 走看看