KMP(複数の一致を重なっていてもよいです)

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

ウリポ

 

問題の説明
フランスの作者ジョルジュ・ペレック(1936-1982)は、文字「E」せずに、ブックオンス、消失を書きました。彼はウリポグループのメンバーでした。書籍からの引用:

すべては通常のペアだったが、偽の自分自身を主張しました。すべては最初に、そして、腹立たしいを非人間的に発生した、通常のフェアを持っていました。彼は小説はいつでも彼の想像力を彼のカーペットの加害者をかき混ぜる統一基づいていた団体、タブーの直感、の暗い悪のビジョンを知りたいと思った空いているものを、言わない:ビジョン、すべてが正常な見えたが、その理由を廃止し、すべてを、忘れコマンダーAVISION ...

Perecは、おそらく、次のコンテストに高い(というか、低い)得点だろう。人々は、できるだけ与えられた「言葉」のように、いくつかの出現でいくつかのテーマにおそらく意味のある文章を書くことが求められます。私たちの仕事は、競合他社のランキングを得るために、これらの発生を数えるプログラムで陪審員を提供することです。これらの競合他社は、多くの場合、ナンセンスな意味を持つ、非常に長い文章を書きます。50万連続した「Tさんのシーケンスは珍しいことではありません。そして、彼らはスペースを使用することはありません。

だから我々はすぐにどのくらいの頻度単語、すなわち、与えられた文字列を検索する、テキストで発生します。より正式:アルファベット{「A」、「B」、「C」、...、「Z」}とそのアルファベット上の2つの有限の文字列を与えられ、ワードWとテキストTは、TにおけるWの出現回数を数えます。Wのすべての連続した文字は正確にT.出現の連続した文字が重なることが一致している必要があります。

 

 

入力
入力ファイルの最初の行は、単一の番号が含まれている:テストケースの数が追従します。各テストケースは、以下のフォーマットを有する:

ワードWの一つの行、1≤と{ 'A'、 'B'、 'C'、...、 'Z'}上の文字列、| Wを| ≤万(ここでは| W |文字列Wの長さを表します)。
テキストT、上列{ 'A'、 'B'、 'C'、...、 'Z'}と1本のラインと| W | ≤| T | ≤1,000,000。
 

 

出力
入力ファイル内のすべてのテストケースのために、出力は、単一の行に、単一の番号を含める必要がありますテキストT.における単語Wの出現回数を

 

 

サンプル入力
3 BAPC BAPC AZA AZAZAZA VERDI AVERDXIVYERDIAN
 

 

サンプル出力
1 3 0
 

 

ソース
 

 

推薦します
LCY | 我々は慎重にあなたのためのいくつかの同様の問題を選択している:   1358   3336   3746   2203   2222
#include <cstdioを> 
する#include <CStringの> 
する#include <cmath> 
の#include <アルゴリズム> 
の#include <iostreamの> 
する#include <アルゴリズム> 
の#include <iostreamの> 
する#include <cstdioを> 
する#include < ストリング > 
の#include <CStringの> 
書式#include <stdio.hに> 
する#include < 文字列の.h>
 使用して 名前空間はstdを、
const  int型 N = 500009 ;
int型のC [N]。
int型のn;
// int型のP [220009]。
[ 1000009 ];
 CHAR B [ 10009 ]; 


無効 GetNextの(チャー * B、INT * NEXT)
{ 
    int型 LEN = STRLEN(B)を、
     INT J = 0、Kが= - 1 ; 
    次に[ 0 ] = - 1。;
     一方(Jは<LEN)// 単語の末尾を次回追加されるため、低減させることがないLEN見つけて複数回重複していてもよい、また、次のクエリで使用される必要があります。
    {
         IF(K == - 1 || B [K] == B [J])
        { 
            K ++ 
            J++ ;
             // 配列巣下最適化
            IF(B [K] =!B [J])
                次に[J] = K;
             
                次に[J] = 次に[K]; 
        } 
        そうでなければ
        { 
            K = 次に[K] ; 
        } 
    } 
} 

int型のmain()
{ 
    int型N-; 
    scanfの(" %のD "、およびN-)、
     一方(N-- 
    { 
        INT次に[ 10009 ]; 
        scanfの(" %S " 、B)。
        scanf関数(" %sの" 、A)。
        INTレナ= STRLEN(A)、LENB =のSTRLEN(B)。
        GETNEXT(B、NEXT)。
        int型 I = 0、J = 0 ;
        int型 ANS = 0 ;
        一方(iは< レナを)
        { 
            場合(J == - 1 || [I] == B [J])
            { 
                iは ++ 
                J ++ ; 
            } 
            他の 
            {
                J = 次の[J]。
            } 
            であれば(J == LENB)
            { 
                ANS ++ 
                J = 次の[J]。
            } 
        } 
        のprintf(" %d個の\ n " 、ANS)。
    } 



    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/nonames/p/11285550.html