[Leetcode] Implement strStr()
10681 ワード
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
KMPアルゴリズム!
上は通常KMPアルゴリズムを用いているが,アルゴリズムには一定の欠陥がある.例えば,我々のパターン列pattern=「AAAAAAB」では,next配列が01230であることが容易に得られる.ターゲットマッチング列が「AAAACAAAAB」であれば、シミュレーションしてみてください.Aは何度も遡ります.すなわち,我々のnext配列最適化は徹底的ではない.最適化アルゴリズム:next[i]は、マッチング列がiでマッチングに失敗した場合に次に移動する位置を表す.以下は最適化後のnext配列を求めるコードです.2つの書き込みでnext値が異なるが,kmp関数の書き方は同じである.
以下はKMPアルゴリズムではありませんが、コードは特に簡潔です.
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
KMPアルゴリズム!
1 class Solution {
2 public:
3 void getNext(vector<int> &next, string &needle) {
4 int i = 0, j = -1;
5 next[i] = j;
6 while (i != needle.length()) {
7 while (j != -1 && needle[i] != needle[j]) j = next[j];
8 next[++i] = ++j;
9 }
10 }
11 int strStr(string haystack, string needle) {
12 if (haystack.empty()) return needle.empty() ? 0 : -1;
13 if (needle.empty()) return 0;
14 vector<int> next(needle.length() + 1);
15 getNext(next, needle);
16 int i = 0, j = 0;
17 while (i != haystack.length()) {
18 while (j != -1 && haystack[i] != needle[j]) j = next[j];
19 ++i; ++j;
20 if (j == needle.length()) return i - j;
21 }
22 return -1;
23 }
24 };
上は通常KMPアルゴリズムを用いているが,アルゴリズムには一定の欠陥がある.例えば,我々のパターン列pattern=「AAAAAAB」では,next配列が01230であることが容易に得られる.ターゲットマッチング列が「AAAACAAAAB」であれば、シミュレーションしてみてください.Aは何度も遡ります.すなわち,我々のnext配列最適化は徹底的ではない.最適化アルゴリズム:next[i]は、マッチング列がiでマッチングに失敗した場合に次に移動する位置を表す.以下は最適化後のnext配列を求めるコードです.2つの書き込みでnext値が異なるが,kmp関数の書き方は同じである.
1 class Solution {
2 public:
3 void getNext(vector<int> &next, string &needle) {
4 int i = 0, j = -1;
5 next[i] = j;
6 while (i < needle.length() - 1) {
7 while (j != -1 && needle[i] != needle[j]) j = next[j];
8 ++i; ++j;
9 // , 。 AAAAB, 4 A 0123 。
10 if (needle[i] == needle[j]) next[i] = next[j];
11 else next[i] = j;
12 }
13 }
14 int strStr(string haystack, string needle) {
15 if (haystack.empty()) return needle.empty() ? 0 : -1;
16 if (needle.empty()) return 0;
17 vector<int> next(needle.length() + 1);
18 getNext(next, needle);
19 int i = 0, j = 0;
20 while (i != haystack.length()) {
21 while (j != -1 && haystack[i] != needle[j]) j = next[j];
22 ++i; ++j;
23 if (j == needle.length()) return i - j;
24 }
25 return -1;
26 }
27 };
以下はKMPアルゴリズムではありませんが、コードは特に簡潔です.
1 class Solution {
2 public:
3 int strStr(string haystack, string needle) {
4 int i, j;
5 for (i = j = 0; i < haystack.size() && j < needle.size();) {
6 if (haystack[i] == needle[j]) {
7 ++i; ++j;
8 } else {
9 i -= j - 1; j = 0;
10 }
11 }
12 return j != needle.size() ? -1 : i - j;
13 }
14 };