KMP 算法的数学推导

         不论从逻辑上怎么分析KMP算法,只要不给出具体的数学公式,都是不严谨的,直到看了KMP算法的数学公式,我才真正理解了该算法。

 

         假设有一个待匹配的源字符串S,其数学表达式如下:

        


         接下来我们还有一个模式字符串t,其数学表达式如下:

        

        

假设存在整数 I 和 j(0 < I <=m,0 < j <= n),使得

-------------------------------------------------公式1


那么必然存在正整数 k,0 < k< j – 1,使得

---------------------------------------------公式2


假设有

-------------------------------------------公式3


联立2、3式可得:


由此可知 都不用比较了。

 

KMP 算法的数学推导_第1张图片

C++ 版代码实现:

#include  
#include  
#include  

using namespace std;

void get_next(const string pat, vector& next)
{
	next.resize(pat.length(), 0);
	int i = 1, j = 0;
	while (i < pat.length() - 1) {
		if (pat[i] == pat[j])            // matched.  
			next[++i] = ++j;            // record next.  
		else if (j != 0)                // doesn't matched.  
			j = next[j];                // back trace.  
		else                            // nomatched.  
			next[++i] = 0;
	}//while  
}

void Index_KMP(const string str, const string pat, vector& inds)
{
	vector next;
	get_next(pat, next);
	inds.clear();

	int i = 0, j = 0;
	while (i < str.length()) {
		if (str[i] == pat[j])
		{                               // matched.  
			++i; ++j;                   // move on.  
			if (j >= pat.length()) {
				inds.push_back(i - pat.length());
				j = 0;                  //reset.  
			}
		}
		else if (j != 0)            // back trace.  
			j = next[j];
		else                          // impossible.  
			++i;
	}//while  
}
int main(void)
{
	string str1, str2;

	while (cin >> str1 >> str2) {
		vector inds;
		Index_KMP(str1, str2, inds);
		for (int i = 0; i < inds.size(); ++i) {
			cout << inds[i] << " ";
		}
		cout << endl;
		cout.flush();
	}//while.  
	return 0;
}



你可能感兴趣的:(数据结构与算法)