序文:
21.再テストに参加できるかどうかに関係なく、道路に書かれたゴミコードを記録します。もともと「AlgorithmNotes」をかじったのですが、やりすぎたので、Kingway ComputerTestGuideに変更しました。
タイトル説明:
テキスト内のパターンのすべての出現を見つけることは、テキスト編集プログラムで頻繁に発生する問題です。通常、テキストは編集中のドキュメントであり、検索されるパターンはユーザーが指定した特定の単語です。テキストは長さnの配列T [1…n]であり、パターンは長さm <= nの配列P [1…m]であると想定します。さらに、PとTの要素はすべてアルファベットであると想定します。 (∑ = {a、b…、z})。文字配列PおよびTは、文字列と呼ばれることがよくあります。パターンPは、0 <= s <= nかつT [s + 1…s + m] = P [1…m]の場合(つまり、T [s + j] =の場合)、テキストTのシフトsで発生すると言います。 P [j]、1 <= j <= mの場合)。TのシフトsでPが発生する場合は、有効なシフトと呼びます。それ以外の場合は、無効なシフトと呼びます。あなたの仕事は、与えられたテキストTとパターンPのvaldシフトの数を計算することです。
説明を入力してください
いずれの場合も、1行に2つの文字列TとPがあり、1つのスペースで区切られています。TとPの両方の長さが10 ^ 6を超えないと想定できます。
出力の説明:
別の行に数値を出力する必要があります。これは、指定されたテキストTとパターンPの有効なシフトの数を示します。
回答
#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int MAXN = 1000 + 10;
void getnext(int next[], string t) {
int k = -1, j = 0;
next[0] = -1;
while (j < t.length() -1 )
if (k == -1 || t[k] == t[j])
next[++j] = ++k;
else
k = next[k];
return;
}
int KMP(string text,string t,int next[]) {
int i = 0, j = 0;
int count = 0;
while (i < (int)(text.length()) && j < (int)(t.length())) {
//注意一定要加强制类型转换,length()返回的是无符号数,若不加当j=-1,比较的时候j被转为无符号数,会变得很大,导致bug
if (j == -1 || text[i] == t[j]) {
i++;
j++;
}
else
j = next[j];
if (j == t.length()) {
i = i - j + 1;
j = 0;
count++;
}
}
return count;
}
int main() {
string text, pattern;
while (cin >> text >> pattern) {
int next[MAXN];
getnext(next, pattern);
cout << KMP(text, pattern, next) << endl;
}
return 0;
}
STLのfind()を使用すると非常に便利ですが、今日KMPアルゴリズムの学習を終えたばかりであり、それでも手動で実装したいと考えています。stringのlength()は符号なしの数値を返します。これは本当にばかげています。長い間考えた後、私はそれを理解していません。