模式匹配算法之brute force

本文探讨了串的基本概念,如串、子串等,并详细介绍了模式匹配中的brute force算法,该算法通过逐字符比较实现字符串匹配。文章通过简单的代码示例展示了算法的工作原理,并预告将分享更高效的KMP算法。

终于学完串这个章节,这就利用两篇文章来谈一谈学习的心得!

串的应用是比较贴近生活的,最常用的例子就是用搜索引擎的时候,我们输入一个字符,它就会帮我们做了模式匹配的工作,如图:



功能如此强大,还贴近生活,还解决了各种单身汉的问题,所以串这种数据结构一定要掌握清楚!


首先是,阐述一下串的几个概念:

1、串:(string)是由零个或多个字符组成的有限序列,又名字符串;

2、串的长度:串中的字符数目n称为串的长度;

3、空串:零个字符的串称为空串;

4、空格串:只包含空格的串。(注意与空串的区别)可以是很多空格;

5、子串:串中任意个数的连续字符组成的子序列,重要概念,本算法的重点概念。


算法简介:brute force有道翻译是野蛮暴力,书上的翻译叫朴素的模式匹配! 反差巨大啊,不过这两个名字都很形象的说明了这个算法的精要。

简单的说,就是对主串的每一个字符作为子串的开头,与要匹配的字符串进行匹配,对主串做大循环,同时对子串进行进行小循环,直到匹配成功或者全部遍历完成为止!


代码:

首先把我的串的定义写出来,按个人方式写,我的是模仿书上的方式,为了匹配后面的KMP算法而设计的串:

typedef struct{			/*串的定义*/
	char str[255];
	int size;
}SString;

void StrAssign(SString * T, char *a)		/*串是从为序1开始的,0位放置数组的大小*/
{
	int n=strlen(a);
	memset(T->str,0,255);
	T->str[0]=n;
	strcat(T->str,a);
	T->size=n;
}

void StrShow(SString * T)			/*利用StrShow正确显示*/
{
	for (int i=1;i<=T->size;i++)
	{
		cout<<T->str[i];
	}
	cout<<endl;
}



然后是算法的主要部分:我会好好的做注释

int indext_BF(SString * S,SString * T,int pos)
{								/*返回T串在S串中第pos个字符以后的位置,若不存在返回0*/
	int i=pos;			/*主串的位置下标*/
	int j=1;			/*子串的当前位置下标*/
	while (i<=S->str[0] && j<=T->str[0])		/*若i小于S的长度,且j小于T的长度时循环*/
	{
		if (j==0 || S->str[i]==T->str[j])		/*两字母相等则继续*/
		{
			i++;
			j++;
		} 
		else
		{
			i=i-j+2;j++;			//主串和子串进行回溯操作
		}
	}
	if(j>T->str[0])			//判断是否匹配,当j大于子串的长度时说明匹配成功了
	{
		return i-T->str[0];
	}
	else
	{
		return 0;
	}
}




输出结果为:



由于暴力匹配的思路和代码是比较简单的,这里就不多做解释,明天我会将KMP算法发布出来!


### Brute Force 模式匹配算法的原理与 C++ 实现 #### 算法原理 Brute Force(BF)模式匹配算法是一种简单的字符匹配方法。其核心思想是通过逐一比较主 `S` 和模式 `P` 中的字符来查找匹配位置。具体来说,从主的起始位置开始,取与模式长度相同的子进行逐字符比较[^3]。如果所有字符都匹配,则返回匹配的起始位置;否则,将主中的比较起点右移一位,继续重复上述过程,直到找到匹配或遍历完整个主[^1]。 #### 时间复杂度分析 在最坏情况下,BF 算法的时间复杂度为 \(O(n \times m)\),其中 \(n\) 是主的长度,\(m\) 是模式的长度。最坏情况发生在每次比较都需要检查到模式的最后一个字符才确定不匹配时[^4]。然而,在平均情况下,BF 算法的表现通常优于最坏情况,尤其是当主和模式中字符分布较为随机时。 #### C++ 实现代码 以下是一个完整的 C++ 实现示例,展示了如何使用 BF 算法在主中查找模式的首次出现位置: ```cpp #include <iostream> #include <string> using namespace std; // Brute Force 模式匹配函数 int bruteForceMatch(const string& text, const string& pattern) { int n = text.size(); // 主长度 int m = pattern.size(); // 模式长度 // 遍历主的所有可能起始位置 for (int i = 0; i <= n - m; i++) { int j; // 对每个起始位置,逐字符比较模式和主 for (j = 0; j < m; j++) { if (text[i + j] != pattern[j]) break; // 如果发现不匹配,跳出循环 } if (j == m) return i; // 如果成功匹配整个模式,返回起始位置 } return -1; // 如果未找到匹配,返回 -1 } int main() { string text = "hello world"; // 主 string pattern = "world"; // 模式 // 调用 BF 匹配函数并输出结果 cout << "Brute Force: " << bruteForceMatch(text, pattern) << endl; return 0; } ``` #### 代码解释 - **输入参数**:函数 `bruteForceMatch` 接收两个字符参数,分别是主 `text` 和模式 `pattern`。 - **外层循环**:外层循环控制主中模式的起始位置,范围是从 `0` 到 `n - m`(即主中可以容纳模式的最大起始位置[^2])。 - **内层循环**:内层循环负责逐字符比较模式和主的子。如果发现不匹配的字符,则立即退出内层循环,并移动到下一个起始位置。 - **返回值**:如果找到匹配的子,返回其在主中的起始位置;否则返回 `-1` 表示未找到匹配[^1]。 --- #### 示例运行 假设主为 `"abababc"`,模式为 `"abc"`,则算法的执行过程如下: 1. 第一次比较:主 `"aba"` 与模式 `"abc"` 不匹配。 2. 第二次比较:主 `"bab"` 与模式 `"abc"` 不匹配。 3. 第三次比较:主 `"abc"` 与模式 `"abc"` 完全匹配,返回起始位置 `4`。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值