質問の意味:
それは、すべての曲は、AとBは、あなたが最大の長さEをご覧いただくことがあることができないこのタイプ、EAEBEあり、あります
ソリューション:
最初のアイデア:
最小1から始めて、同じ最大程度の頭と尾のうちの誰かを見つけることができ、最大/ 3 LEN未満であります
そして、それの中央部と同じではありません見つけるためにKMPアルゴリズムを使用します
しかし、このような方法があまりにも面倒なだけでなく、文字列を切断され、以下を参照してください
第二:
私たちは、彼の次の配列KMPを探し出すことで起動することができます
そのようなプレフィックスおよびEのみ、次の[i]が中間次の[LEN]に等しい見つけるために、満たされたサフィックス
コード:
1の#include <stdio.hの> 2の#include < ストリング・H> 3の#include <STDLIB.H> 4の#include <アルゴリズム> 5 使って 名前空間STDを、 6 のconst int型 MAXN = 1E6 + 10 。 7 チャーPTR [MAXN]。 8 INT [MAXN] NNN。 9 ボイド GET_NEXT(INT PLEN) 10 { 11 のint i = 0 、J。 12 J = NNN [ 0 ] = - 1 。 13 一方(iは<PLEN) 14 { 15 ながら!(J = - 1つの!&& PTR [I] = PTR [J])J = NNN [J]。 16 NNN [++ I] = ++ J。 17 } 18 } 19 INT KMP(INT PLEN) 20 { 21 GET_NEXT(PLEN)。 22 のための(int型 ; kは、K = K = NNN [PLEN] NNN [K]) 23 { 24 // のprintf( "%D%D%D \ n"、K、2 * K-1、PLEN-K) ; 25 のために(int型 I = 2 * K- 1 ; iがPLEN-Kを<; ++ i)は 26 { 27 であれば(NNN [I] + 1 == K) 28 リターンK。 29 } 30 } 31 リターン 0 。 32 } 33 のint main()の 34 { 35 のint T。 36 のscanf(" %dの"、&T)。 37 一方(t-- ) 38 { 39 のscanf(" %sの" 、PTR)。 40 int型のlen =STRLEN(PTR)。 41 INT Q = KMP(LEN)。 42 のprintf(" %d個の\ n " 、Q)。 43 } 44 リターン 0 。 45 }