zoukankan      html  css  js  c++  java
  • Hdu 1686 Oulipo

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1686

    字符串匹配,因此采用了KMP算法。有一点需要注意,请看题目的样例2:

    T:  AZA

    S:  AZAZAZ

    很明显T和S的前3位匹配,那么接下来呢?

    我最初设计的程序,T和S的前三位匹配后,T开始与S的第四位进行匹配判断。

    但实际上,S的第三位至S的第五位可以与T匹配。

    为什么会这样呢?

    我思考了之后明白了问题所在:当T在S中找到一个匹配串后,T将第一位与S的下一位进行比较。这实际上可能造成失去发现一个新字符串匹配的机会。

    因此,当T在S中找到一个匹配串后,T不应将第一位与S的下一位进行比较。那应该将T的第几位比呢?其实思考一下就可以知道怎么办。

    将T与自己匹配,当比较结束后,看一下作为待匹配的T最多与模式串T的第几位匹配即可。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int W_MAXN = 10000 + 50;
    char word[ W_MAXN ];
    int next[ W_MAXN ];
    
    const int T_MAXN = 1000000 + 50;
    char text[ T_MAXN ];
    int End;
    
    void Get_next()   //  得到next数组
    {
    	int i, j = 0;
    	next[ 1 ] = 0;
    	int length = strlen( word+1 );
    	for( i=2;i<=length;i++ )
    	{
    		next[i] = j;
    		if( word[i]!=word[ j+1 ] )
    		{
    		    	j = next[ j+1 ];
    		}
    		else
    		{
    		    	j ++;
    		}
    	}
    }
    
    void Get_End()
    {
    	int i, j = 0;
       	int finish = strlen ( word+1 );
    	for( i=2; i<=finish;i++ )
    	{
    		while( j>0 && word[i]!=word[j+1] )
    		{
    			j = next[ j+1 ];
    		}
    		if( word[i]==word[j+1] )
    		{
    			j ++;
    		}
    	}
    	End = j;
    }
    
    int Count()
    {
        int counter = 0;
        int i, j = 0;
        int finish = strlen ( word+1 );
        int length = strlen ( text+1 );
        for( i=1;i<=length;i++ )
        {
            while( j>0 && text[i]!=word[ j+1 ] )
            {
                j = next[ j+1 ];
            }
            if( text[i] == word[j+1] )
            {
                j ++;
            }
            if( j==finish )
            {
                j = End;  // 不应 j = 0
                counter ++;
            }
        }
        return counter;
    }
    
    int main()
    {
        int T;
        scanf( "%d", &T );
        while( T-- )
        {
            scanf( "%s", word+1 );
            scanf( "%s", text+1 ); // 为方便, 均从第一位读起
            Get_next();
            Get_End();
            printf( "%d
    ", Count() );
        }
        return 0;
    }
    
  • 相关阅读:
    POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
    LCA 最近公共祖先 (模板)
    线段树,最大值查询位置
    带权并查集
    转负二进制
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
  • 原文地址:https://www.cnblogs.com/Emerald/p/4156120.html
Copyright © 2011-2022 走看看