/*<br />KMP演算法是一種改進的字串匹配演算法,由D.E.Knuth與V.R.Pratt和J.H.Morris同時發現,因此人們稱它為克努特——莫裡斯——普拉特操作(簡稱KMP演算法).<br />KMP演算法的關鍵是根據給定的模式串W1,m,定義一個next函數,next函數包含了模式串本身局部匹配的資訊.<br />*/<br />#include <iostream><br />#include <vector><br />#include <functional><br />#include <algorithm><br />using namespace std;<br />template<typename FType, typename SType><br />struct equal_cmp<br />{<br />bool operator ()(const FType& _F, const SType& _S)const<br />{<br />return _F == _S;<br />}<br />}; </p><p>template<typename RandAccessConcept, typename EqualCmp><br />inline void CalFailFunction(const RandAccessConcept& in, int len, vector<int>& ff, EqualCmp cmp )<br />{<br />ff.clear();<br />ff.reserve(len);<br />ff.push_back(-1);<br />for (int curr = 1, k = -1; curr < len; ++curr)<br />{<br />for (;k >= 0 && !cmp(in[k+1], in[curr]); k = ff[k]);<br />if (cmp(in[k+1], in[curr])) ++k;<br />ff.push_back(k);<br />}<br />} </p><p>template<typename FRandAccessConcept, typename SRandAccessConcept, typename EqualCmp><br />inline int KMPSearchFirst(const FRandAccessConcept& d, int dlength, const SRandAccessConcept& p, int plength, EqualCmp cmp, int start = 0)<br />{<br />vector<int> ff;<br />CalFailFunction(p, plength, ff, cmp);<br />for (int i = start, j = -1; i < dlength; ++i)<br />{<br />while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];<br />if (cmp(d[i], p[j+1])) ++j;<br />if (j == plength - 1) return i - plength + 1;<br />}<br />return -1;<br />} </p><p>template<typename FRandAccessConcept, typename SRandAccessConcept, typename EqualCmp><br />inline int KMPSearchALL(const FRandAccessConcept& d, int dlength, const SRandAccessConcept& p, int plength, vector<int>& result, EqualCmp cmp)<br />{<br />vector<int> ff;<br />CalFailFunction(p, plength, ff, cmp);<br />result.clear();<br />for (int i = 0, j = -1; i < dlength; ++i)<br />{<br />while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];<br />if (cmp(d[i], p[j+1])) ++j;<br />if (j == plength - 1)<br />{<br />result.push_back(i - plength + 1);<br />j = ff[j];<br />}<br />}<br />return result.size();<br />}<br />//測試<br />int main()<br />{<br />int d[] = {1,2,3,1,2,3,1,2};<br />char p[] = "/1/2/3/1/2";<br />vector<int> result;<br />int found = KMPSearchALL(d, 8, p, 5, result, equal_cmp<int, char><br />()); </p><p>for (int i = 0; i < found; ++i)<br />{<br />cout << result[i] << " ";<br />}<br />cout << endl; </p><p>return 0;<br />}<br />