趣学数据结构--第四章:字符串

趣学数据结构--->第四章:字符串

模式匹配算法

包括BF,KMP算法

模式匹配:子串的定位运算称为串的模式匹配或串匹配
BF(Brute Force)算法:穷举S的所有子串,判断是否与T匹配。

#include <iostream>
using namespace std;


#define Maxsize 100
typedef char SString[Maxsize + 1]; // 0 号单元存放串的长度


// BF 算法
// 求 T 在主串 S 中第 pos 个字符之后第一次出现的位置
// 其中,T 非空,1≤pos≤s[0],s[0]存放S串的长度
int Index_BF(SString s, SString T, int pos)
{
	int i = pos, j = 1, sum = 0;
	while (i <= s[0] && j <= T[0])
	{
		sum++;
		if (s[i] == T[j]) // 如果相等,则继续比较后面的字符
		{
			i++;
			j++;
		}
		else
		{
			i = i - j + 2;   //i 退回到上一轮开始比较的下一个字符
			j = 1;           //j 退回到第1个字符
		}
	}
	cout << "一共比较了" << sum << "次" << endl;
	if (j > T[0])  // 匹配成功
		return i - T[0];  // 返回匹配成功的位置
	else
		return 0;
}



// 求模式串 T 的 next 函数值
void get_next(SString T, int next[])
{
	int j = 1;
	int k = 0;
	next[1] = 0;
	while (j < T[0])  // T[0] 为模式串 T 的长度
	{
		if (k == 0 || T[j] == T[k])
			next[++j] = ++k;
		else
			k = next[k];
	}
	cout << "-----next[]-----" << endl;
	for (j = 1; j <= T[0]; j++)
		cout << next[j] << "  ";
	cout << endl;
}


//计算next函数值改进算法
void get_next2(SString T, int next[])
{
	int j = 1, k = 0;
	next[1] = 0;
	while (j < T[0])
	{
		if (k == 0 || T[j] == T[k])
		{
			j++;
			k++;
			if (T[j] == T[k])
				next[j] = next[k];
			else
				next[j] = k;
		}
		else
			k = next[k];
	}
	cout << "-----next[]-----" << endl;
	for (j = 1; j <= T[0]; j++)
		cout << next[j] << "  ";
	cout << endl;
}


// KMP 算法
// 利用模式串 T 的next 函数求 T 在主串 S 中第pos个字符之后的位置
// 其中,T 非空,1≤pos≤s[0],s[0]存放S串的长度
int Index_KMP(SString s, SString T, int pos, int next[])
{
	int i = pos, j = 1,sum = 0;;
	while (i <= s[0] && j <= T[0])
	{
		sum++;
		if (j == 0 || s[i] == T[j])
		{
			i++;
			j++;
		}
		else
			j = next[j];  // 模式串向右移动
	}
	cout << "一共比较了" << sum << "次" << endl;
	if (j > T[0])
		return i - T[0];
	else
		return 0;
}

//生成一个其值等于chars的串T
bool StrAssign(SString& T, char* chars)
{
	int i;
	if (strlen(chars) > Maxsize)
		return false;
	else
	{
		T[0] = strlen(chars);
		for (i = 1; i <= T[0]; i++)
		{
			T[i] = *(chars + i - 1);
			cout << T[i] << "  ";
		}
		cout << endl;
		return true;
	}
}

int main()
{
	SString S, T;
	char str[100];

	cout << "串S:" << "  ";
	cin >> str; //aabaaabaaaabea
	StrAssign(S, str);//可以修改程序,自己输入字符串 
	
	cout << "串T:" << "  ";
	cin >> str;//aaaab
	StrAssign(T, str);

	int* p = new int[T[0] + 1]; //生成T的next数组
	cout << endl;

	cout << "BF算法运行结果:" << endl;
	cout << "主串和子串在第" << Index_BF(S, T, 1) << "个字符处首次匹配\n";
	cout << endl;

	cout << "KMP算法运行结果:" << endl;
	get_next(T, p);
	cout << "主串和子串在第" << Index_KMP(S, T, 1, p) << "个字符处首次匹配\n";
	cout << endl;

	cout << "改进的KMP算法运行结果:" << endl;
	get_next2(T, p);
	cout << "主串和子串在第" << Index_KMP(S, T, 1, p) << "个字符处首次匹配\n";

	return 0;
}

字符串的应用

病毒检测

#include <iostream>
using namespace std;

#define Maxsize 100
typedef char SString[Maxsize + 1];		//0号单元存放串的长度


//生成一个其值等于chars的串T
bool StrAssign(SString& T, char* chars)
{
	int i;
	if (strlen(chars) > Maxsize)
		return false;
	else
	{
		T[0] = strlen(chars);//0号单元存放串的长度
		for (i = 1; i <= T[0]; i++)
		{
			T[i] = *(chars + i - 1);
			cout << T[i] << "  ";
		}
		cout << endl;
		return true;
	}
}


//计算next函数值改进算法
void get_next2(SString T, int next[])
{
	int j = 1, k = 0;
	next[1] = 0;
	while (j < T[0])
	{
		if (k == 0 || T[j] == T[k])
		{
			j++;
			k++;
			if (T[j] == T[k])
				next[j] = next[k];
			else
				next[j] = k;
		}
		else
			k = next[k];
	}
}

// KMP 算法
// 利用模式串 T 的next 函数求 T 在主串 S 中第pos个字符之后的位置
// 其中,T 非空,1≤pos≤s[0],s[0]存放S串的长度
int Index_KMP(SString s, SString T, int pos)
{
	int* next = new int[T[0] + 1]; // 生成T的next数组
	get_next2(T, next);
	int i = pos, j = 1;
	while (i <= s[0] && j <= T[0])
	{
		if (j == 0 || s[i] == T[j])
		{
			i++;
			j++;
		}
		else
			j = next[j];  // 模式串向右移动
	}
	if (j > T[0])
		return i - T[0];
	else
		return 0;
}


// 病毒检测
bool Virus_detection(SString S, SString T)
{
	int i, j;
	SString temp;//temp记录病毒变种
	for (i = T[0] + 1, j = 1; j <= T[0]; i++, j++) //将T串扩大一倍,T[0]为病毒长度
		T[i] = T[j];

	for (i = 0; i < T[0]; i++)
	{
		temp[0] = T[0];  病毒变种长度为T[0]
		for (j = 1; j <= T[0]; j++)
			temp[j] = T[i + j];
		if (Index_KMP(S, temp, 1))
			return 1;
	}
	return 0;
}

int main()
{
	SString S, T;
	char str[100];
	cout << "患者DNA序列S:" << "  ";
	cin >> str;//eabbacab
	StrAssign(S, str);

	cout << "病毒DNA序列T:" << "  ";
	cin >> str;//aabb
	StrAssign(T, str);

	if (Virus_detection(S, T))
		cout << "该患者已感染病毒!" << endl;
	else
		cout << "该患者未感染病毒!" << endl;

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一记绝尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值