説明タイトル:すべての位置におけるパターン文字列Sで発生開始添字Pテンプレート文字列を取得します。
ヒント:
1.nextアレイのためのより多くの、全体の文字列Pを接頭辞と接尾辞マッチの最大長さを求めます。
マッチが成功した場合には2、p個の文字列がどのくらい押し戻さ?次は、完全一致を有しており、全体のみ文字列が開始比較ラインを示す接頭辞と接尾辞の最大長さと一致I2を位置決めするためにジャンプするには、この時点では、I1文字列ポインタのポイントSであり;矛盾が想定相反する証拠を押します。
3.インデックスの位置は、添え字の長さに対応する、0から始まります。
4.next例えばCN = I-1とプロセスの0、非常に巧妙として再帰的配列、プロセスの開始を感じます。
// 1.記念の醜い、あるいは絵にもかかわらず、相対的に低いで書かれた最初のコード
// ポイントは、論理エラーを感じていないです、長い時間のため2.カードは、出力が間違っている、それはそれの原因は何ですか??
// ないwhileループ上の位置の出力文
// 最初のマッチが成功した後、3試合を続行するためにどのようにして、自分自身で完全にプッシュ?
// 私の次のソリューションは、Pは、最長の接頭辞と接尾辞の長さに一致する文字列全体を見つけ、いずれかのより多くの配列を見つけることであるとき、最長
// マッチが成功した場合、i1は次の位置に正確に一致点を有し、および
/ / 4.矛盾によって証明:i2のポインタジャンプや位置合わせを却下することはできません成功する、すなわち長く表示されていない接頭辞と接尾辞と一致した
@ 5同じ方法です。前伴わない、2同じ文字列である
。// 6なお、比較の完了、I2更新後の添字I1ポインタ
の#include <iostreamの>
する#include <cstdioを>
する#include < 文字列・H>
使用して 名前空間STD;
のconst int型 N = 10010 ;
のconst int型M = 100010 ;
チャーP [N]、S [M]。
INT NE [N]。
INTのN、M。
ボイド getne(チャー *のP){
int型 PLEN = STRLEN(P)。
ない[ 0 ] = - 1 。
NE [ 1 ] = 0 ;
int型 I = 2 ;
int型のcn = 0 ;
しながら、式(I = < {PLEN)
もし(P [I- 1 ] == P [CN]){
やる[I ++] = ++ CN;
} そう であれば(CN> 0 ){
CNは =いないNO [CN]を。
} 他{
NE [I ++] = 0 ;
}
}
/ *
以下のために(INT i = 0; iが= PLEN <; iは++します){
printf( "%dの"、NE [I])。
}
* /
リターン。
}
INT {main()の
CIN >> N >> P >> M >> S。
getne(P)。
INT PLEN = STRLEN(P)。
INT SLEN = STRLEN(S)。
int型 I1 = 0 ; // 甲指针
int型 I2 = 0 ; // 乙指针
ため(; I1 <M、I1 ++ ){
一方(I1 <I2 SLEN && < PLEN){
もし、(S [I1] == P [I2]){
I1 ++ ;
I2 ++ ;
}
他の IF(NE [I2] == -は、1)// NE [I2]何時間が-1であると思いますか?、i2は列P 0の先頭を指すされた1 -場合NE [I2] ==
{
I1 ++ ;
}
他の{
I2 = NO [I2]。
}
もし(I2 == PLEN){
printf(" %dの"、I1- PLEN)。
I2 = NO [I2]。
}
}
}
リターン 0 ;
}
PS:KMPだけでロックが解除され、学習は一週間の時間について費やし
REF:神を残しただけでなく、オンラインのブログ、ありがとう!