栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言字符匹配(BF、RK、KMP)完整代码

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言字符匹配(BF、RK、KMP)完整代码

C语言字符匹配

  1. 暴力BF
  2. 哈希RK
  3. KMP
#include 
#include 
#include 

#define MAXLEN 255
//模式串的匹配
//顺序串
typedef struct {
	char* ch;
	int length;
}SString;

//串的初始化(主串)
void initStringa(SString* s) {
	//s->ch = "GTGTGAGCTGGTGTGTGCFAA";
	s->ch = "aabaabaabaaf";
	s->length = 21;
}

//串的初始化(模式串)
void initStringb(SString* s) {
	//s->ch = "GTGTGCF";
	s->ch = "aabaaf";
	s->length = 7;
}

//BF(暴力 时间复杂度:mn)
bool BF(SString* s, SString* pattern) {
	int j = 0;	//模式串的下标
	for (int i = 0; i < s->length;)
	{
		if (s->ch[i] == pattern->ch[j])
		{
			i++;
			j++;
			if (j == pattern->length)
			{
				return true;
			}
			else
			{
				continue;
			}
		}
		else
		{
			i = i - j + 1;
			j = 0;
			continue;
		}
	}
	return false;
}

//RK(利用哈希值先进行筛选 时间复杂度:n)============start
//获取哈希值
int getHash(SString* s, int index, int length) {
	int hashVal = 0;
	for (int i = 0; i < length; i++)
	{
		hashVal += s->ch[i + index] - 'A';
	}
	return hashVal;
}

//比较主串具体下标开始,模式串长度的子串与模式串是否匹配
bool specificSToPattern(SString* s, int index, SString* pattern) {
	for (int i = 0; i < pattern->length; i++)
	{
		if (s->ch[i + index] != pattern->ch[i])
		{
			return false;
		}
	}
	return true;
}

//获取主串下一个哈希值(index下一个位置的哈希值)
int getNextHash(int sHash, char head, char tail) {
	return sHash - (head - 'A') + (tail - 'A');
}

bool RK(SString* s, SString* pattern) {
	//获取模式串的哈希值
	int pHash = getHash(pattern, 0, pattern->length);
	printf("%d=====模式串的哈希值n", pHash);
	//获取主串对应长度的哈希值
	int sHash = getHash(s, 0, pattern->length);
	printf("%d=====主串的哈希值n", sHash);

	for (int i = 0; i < s->length - pattern->length + 1; i++)
	{
		if (sHash == pHash)
		{
			//开始比较主串从下标i开始到pattern长度的字符是否与模式串匹配
			bool flag = specificSToPattern(s, i, pattern);
			if (flag) {
				printf("匹配成功n");
				return true;
			}
			else
			{
				continue;
			}

		}
		else
		{
			//获取主串下一位置的哈希值
			sHash = getNextHash(sHash, s->ch[i], s->ch[i + pattern->length]);
			printf("主串的第%d个位置的哈希值======>%dn", i + 1, sHash);
		}
	}
	return false;
}
//RK(利用哈希值先进行筛选 时间复杂度:n)============end

//KMP(t主要是利用next数组来进行匹配回溯,这里面关键是主串不需要回溯,时间复杂度:m+n)==========start
//获取next数组
void getNext(int* next, SString* pattern) {
	int j = 0;
	next[0] = 0;
	for (int i = 1; i < pattern->length; i++)
	{
		while (j > 0 && pattern->ch[i] != pattern->ch[j])
		{
			j = next[j - 1];
		}
		if (pattern->ch[i] == pattern->ch[j])
		{
			j++;
		}
		next[i] = j;
	}
}
bool KMP(SString* s, SString* pattern) {

	int* next = (int*)malloc(sizeof(int) * pattern->length);
	getNext(next, pattern);		//获取next数组

	int j = 0;		//模式串的下标
	for (int i = 0; i < s->length, j < pattern->length;)
	{

		if (s->ch[i] == pattern->ch[j])
		{
			printf("%d==相等==%d==j==>%d===i===>%dn", s->ch[i], pattern->ch[j],j,i);
			j++;
			i++;
			if (j == pattern->length)
			{
				printf("匹配成功n");
				return true;
			}
			continue;
		}
		else
		{
			printf("%d==不相等==%d===j=》%d==i==>%dn", s->ch[i], pattern->ch[j], j,i);
			if (j > 0) {
				j = next[j - 1];
			}
			else
			{
				i++;
			}
		}
	}
	return false;
}


//KMP(t主要是利用next数组来进行匹配回溯,这里面关键是主串不需要回溯,时间复杂度:m+n)==========end




void main() {
	SString s;
	SString pattern;
	initStringa(&s);
	initStringb(&pattern);

	printf("测试BF========startn");
	if (BF(&s, &pattern))
	{
		printf("匹配成功n");
	}
	else
	{
		printf("匹配失败n");
	}
	printf("测试BF========endn");

	printf("测试RK========startn");
	if (RK(&s, &pattern))
	{
		printf("匹配成功n");
	}
	else
	{
		printf("匹配失败n");
	}
	printf("测试RK========endn");

	printf("测试KMP========startn");
	if (KMP(&s, &pattern))
	{
		printf("匹配成功n");
	}
	else
	{
		printf("匹配失败n");
	}
	printf("测试KMP========endn");
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030018.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号