数据结构(三)字符串BF算法和KMP算法

一:代码实现

#include<iostream>
using namespace std;
const int MAXSRTINGLEN=50;
class NewString
{
private:
	char Mystring[MAXSRTINGLEN + 1];
	char Teststring[MAXSRTINGLEN + 1];
	int Mystringlength;
	int Teststringlength;
	int next[100000]={0};
public:
	NewString();
	~NewString()
	{
	}
	int BFstring(int pos);
	int KMPstring(int pos);
	void GetValNext();
	void Display();
};
int NewString::KMPstring(int pos)
{
	int m = Mystringlength; int n = Teststringlength;
	GetValNext();
	int i = 0, j = 0;
	while (i < m && j < n)
	{
		if (j == -1 || Mystring[i] == Teststring[j])
		{
			i++; j++;
		}
		else
		{
			j = next[j];
		}
	}
	if (j == n)
	{
		return i - j;
	//	return -1;
	}
	else
	{
		return -1;
	}
}
void NewString::GetValNext()
{
	next[0] = -1;
	int i = 0; int j = -1;
	while (i < Teststringlength - 1)
	{
		if (j == -1 || Teststring[i] == Teststring[j])
		{
			i++;
			j++;
			next[i] = j;
		}
		else
		{
			j = next[j];
		}
	}
}
NewString::NewString()
{
	int i=0;
	char temp;
	while (cin>>temp)
	{
		if (temp == '0')
		{
			break;
		}
		Mystring[i] = temp;
		i++;
	}
	Mystring[i + 1] = '\0';
	Mystringlength = i;
	i = 0;
	char temp1;
	while (cin >> temp1)
	{
		if (temp1 == '0')
		{
			break;
		}
		Teststring[i] = temp1;
	//	cout << temp;
		i++;
	}
	Teststring[i + 1] = '\0';
	Teststringlength = i;
	next[Teststringlength] = { 0 };
	//	cout << i << endl;
	//GetValNext();
}
int NewString::BFstring(int pos)
{
	int i = pos; int j = 0;
	while (i < Mystringlength && j < Teststringlength)
	{
	//	cout << Mystring[i] << Teststring[j] << endl;
		if (Mystring[i] == Teststring[j])
		{
			i++; j++;
		//	cout << Mystring[i] ;
		//	cout << i << " " << j << endl;
		}
		else
		{
			i = i - j + 1;
			j = 0;
		}
	}
	//cout << j << endl;
	if (j >= Teststringlength)
	{
		return i - Teststringlength;
	}
	else
	{
		return -1;
	}
}
void NewString::Display()
{
	for (int i = 0; i < Mystringlength; i++)
	{
		cout << Mystring[i]<<" ";
	}
	cout << endl;
	for (int i = 0; i < Teststringlength; i++)
	{
		cout << Teststring[i] << " ";
	}
	cout << endl;
}
int main(void)
{
	NewString  *s = new NewString;
	s->Display();
	cout <<"BF匹配位置是" << s->BFstring(0) << endl;
	cout << "KMP匹配的位置是" << s->KMPstring(0) << endl;
	//cout << 1;
	return 0;
}

二:原理:

2.1:BF算法

基本思想:

从主串S的第0个字符开始和模式T 的第0个字符进行比较,     若相等,则继续比较两者的后续字符;     否则,从主串S的第1个字符开始和模式T 的第0个字符进行比较,     重复上述过程,直到T 中的字符全部比较完毕,则说明本趟匹配成功;或S中字符全部比较完,则说明匹配失败。

说明:模式匹配过程要进行多趟的匹配,每趟匹配要进行若干次的比较

1. 在串S和串T中设比较的起始下标i和j;

2. 循环直到S或T的所有字符均比较完;    

2.1 如果S[i]==T[j],继续比较S和T的下一个字符;    

2.2 否则,将i和j回溯(i=i-j+1,j=0),准备下一趟比较;

3. 如果T中所有字符均比较完,则匹配成功,返回匹配的起始比较下标(i-j);否则,匹配失败,返回-1;

 

 

 

 

 

 

 

 

 

 

 

 2.1:KMP算法

 结论: i可以不回溯,模式向右滑动到的新next[j]的算法分析: k=next[j-1](由next[]的 定义可以知道:t0t1…tk-1= tj-k…tj-3tj-2) 1. 如果t[k]==t[j-1]或k==-1(不存在长度相同的前缀子串和左子串)则t0t1…tk-1tk= tj-k…tj-3tj-2tj-1,因此     next[j]=k+1,next[j]计算结束 否则, 查找t0t1…tk的最长左子串        k=next[k],转 1 继续执行

比较起点k ,并且k 仅与模式串T有关!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值