字符串匹配算法之KMP

关于字符串匹配算法KMP的介绍请看这里点击打开链接

这里给出具体的实现代码,用了两天时间才全部实现,好菜的感觉!!!


//字符串匹配的KMP算法
#include <iostream>
#include <vector>
#include <string>

using namespace std;

//建立部分匹配值表
void generateTable(string& str,int table[])
{
	int num = str.length();
	table[0] = 0;
	for(int i=1;i<num;++i)
	{
		string sub_str = str.substr(0,i+1);
		//生成前缀表和后缀表
		string *prefix_str = new string[i]();
		string *suffix_str = new string[i]();	
		for(int j=0;j<i;j++)
		{
			prefix_str[j] = str.substr(0,j+1);
			suffix_str[j] = str.substr(sub_str.length()-j-1,j+1);
		}
		//比较前缀表和后缀表
		int value = 0;
		for(int m=0;m<i;++m)
		{
			for(int n=0;n<i;++n)
			{
				if(prefix_str[m].compare(suffix_str[n]) == 0)
				{
					if(prefix_str[m].length() > value)
						value = prefix_str[m].length();
				}
			}
		}

		table[i] = value;

		delete [] prefix_str;
		delete [] suffix_str;
	}
}
//KMP算法字符串匹配
int KMP(string& A,string& B,vector<int>& loc)
{
	//默认在A中搜索B
	if(A.length() < B.length())
		return 0;
	loc.clear();
	//建立部分匹配值表
	int* table = new int[B.length()];
	generateTable(B,table);
	//字符串搜索
	for(int i=0;i<=(A.length()-B.length());)
	{
		string subStr_A = A.substr(i,B.length());
		if(subStr_A.compare(B)!=0)
		{
			for(int j=0;j<B.length();++j)
			{
				if(subStr_A[j]==B[j])
					continue;
				if(j==0)
					j += 1;
				int shift = j - table[j-1];
				i += shift;
				break;
			}
		}
		else
		{
			loc.push_back(i);
			i += B.length();
		}
	}

	//释放内存
	delete [] table;

	return loc.size();
}


int main(int argc,char* argv[])
{
	string A = "BBC ABCDAB ABCDABCDABDEABCDABD";
	string B = "ABCDABD";

	int *table = new int[B.length()]();

	generateTable(B,table);
	cout<<"Table: ";
	for(int i=0;i<B.length();++i)
	{
		cout<<table[i]<<" ";
	}
	cout<<endl;

	vector<int> vect_loc;
	int loc = KMP(A,B,vect_loc);

	if(loc==0)
		cout<<"没有搜索到相关字符串"<<endl;
	else
	{
		cout<<"搜索到的字符串位置:\n";
		for(int m=0;m<vect_loc.size();++m)
		{
			cout<<"["<<m<<"]: ";
			cout<<vect_loc[m]<<endl;
		}
		cout<<endl;
	}
	
	delete [] table;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值