日曜日のアルゴリズム



Sunday Algorithm



サンデーダニエルM.サンデーアルゴリズムは1990年に文字列パターンマッチングを提案しました。中心的な考え方は、マッチングプロセスでパターンマッチング文字列が見つからない場合、アルゴリズムは次のマッチングのためにできるだけ多くの文字をスキップできるため、マッチング効率が向上するということです。

コアアイデア:マッチングプロセスでは、パターン文字列は、比較を左から右または右から左に押して、不一致が見つかったと比較する必要はありません。アルゴリズムは可能な限りスキップできます キャラクター 次の試合では、マッチング効率が向上します。



コンテンツアルゴリズム:パターン文字列を参照する1はS、部分文字列はT、長さはN、Mです。

2. Tの場合、単純ですが独創的な事前準備を行います。配列に格納されている、記録Tの最後の出現の各文字位置。 3. S [i]≠T [j]、1≤i≤N、1≤j≤Mのときに不一致が発生すると仮定します。 Sを最初に一致する文字位置Lとします。明らかに、S [L + M + 1]は確実に次のラウンドの試合に参加する必要があり、少なくともS [L + M +1]までのTは可能な試合と一致します。 S全体。
4.この場合、T S [L + M +1]の位置が発生するはずです。前処理された配列O(1)を使用して位置uを見つけ、T [u] == S [L + M +1]に直接移動します。特に、S [L + M + 1]がTに表示されない場合、TはS [L + M + 1]に一致することはできず、最初のビットTはS [L + M +2に直接移動します。 ]、一致し続けます。 L + M> Nになると、マッチングが完了します。 文字列の長さに一致する移動ステップ+1 =

たとえばアルゴリズム

S:abcceabcaabcd T:abcdCとdが一致していません。このとき、S [L + M + 1] == 'e'、Tは表示されません。次に:S:abcceabcaabcd T:-------- abcd Dで、不一致が見つかりました。このとき、S [L + M + 1] == 'a'、Tは最後のT [0]に現れます。次に:S:abcceabcaabcd T:-------------- abcd一致に成功しました。 int wei[301]={0} int ans = 0, lend, lenc, tot = 0 // tot matches for statistical frequency for intuitive comparison with other algorithms char c[10001],d[10001] void pei() { int w=0 while(w+lend<=lenc) { int i=0 bool f=false while(i<=lend && f==false) { if(c[i+w]!=d[i])f=true i++tot++ } if (f == false) {ans ++ w ++} // ans can be used to record the number of times of occurrence substring else { i=lend+1 if (wei [c [i + w]] == - 1) w = w + i + 1 // do not match, the next one else w = w + i-wei [c [w + i]] // return to the current at the beginning of the character substring } } return } int main() { gets(c) gets(d) lenc=strlen(c)-1 lend=strlen(d)-1 for(int i=0i<=300++i)wei[i]=-1 for(int i=0i<=lend++i) wei[d[i]]=i pei() if(ans) cout< int wei[301]={0} int ans=0,lend,lenc,tot=0 string c,d void pei() { int w=0 while(w+lend<=lenc) { int i=0 bool f=false while(i>c cin>>d lenc=c.length()-1 lend=d.length()-1 for(int i=0i<=300++i)wei[i]=-1 for(int i=0i<=lend++i) wei[d[i]]=i pei() if(ans) cout<

ps:とりわけBaidu百科事典からの仕上げ