漫画:如何优化 “字符串匹配算法”?

简介: BF算法是如何工作的?正如同它的全称BruteForce一样,BF算法使用简单粗暴的方式,对主串和模式串进行逐个字符的比较。

640.png

说起“字符串匹配”,恐怕算得上是计算机领域应用最多的功能之一,为了满足这一需求,聪明的计算机科学家们发明了许多巧妙的算法。

在上一篇漫画中,我们介绍了BF算法和RK算法,没看过的小伙伴可以先补补课:

漫画:什么是字符串匹配算法?

今天,我们来介绍一种性能大大优化的字符串匹配算法。

 640.jpg640.jpg640.jpg

 

 

BF算法是如何工作的?


 

正如同它的全称BruteForce一样,BF算法使用简单粗暴的方式,对主串和模式串进行逐个字符的比较。

比如给定主串和模式串如下:

 640.png

它们的比较过程是什么样的呢?


 

第一轮,模式串和主串的第一个等长子串比较,发现第0字符一致,第1位字符一致,第2位字符不一致:

 

640.png640.png640.png

 

第二轮,模式串向后挪动一位,和主串的第二个等长子串比较,发现第0位字符不一致:

 

640.png

 

第三轮,模式串继续向后挪动一位,和主串的第三个等长子串比较,发现第0位字符不一致:

640.png


以此类推,一直到第N轮:

 640.png

当模式串挪动到某个合适位置,逐个字符比较,发现每一位字符都是匹配时,比较结束:

640.png640.jpg640.jpg640.jpg640.jpg640.jpg640.jpg

 

坏字符规则


 

“坏字符” 是什么意思?就是指模式串和子串当中不匹配的字符。

还以上面的字符串为例,当模式串和主串的第一个等长子串比较时,子串的最后一个字符T就是坏字符:

 640.png640.jpg640.jpg

当检测到第一个坏字符之后,我们有必要让模式串一位一位向后挪动和比较吗?并不需要。

因为只有模式串与坏字符T对齐的位置也是字符T的情况下,两者才有匹配的可能。

不难发现,模式串的第1位字符也是T,这样一来我们就可以对模式串做一次“乾坤大挪移”,直接把模式串当中的字符T和主串的坏字符对齐,进行下一轮的比较:
640.png

 

坏字符的位置越靠右,下一轮模式串的挪动跨度就可能越长,节省的比较次数也就越多。这就是BM算法从右向左检测的好处。

 

接下来,我们继续逐个字符比较,发现右侧的GCG都是一致的,但主串当中的字符A,是又一个坏字符:

 

640.png

 

我们按照刚才的方式,找到模式串的第2位字符也是A,于是我们把模式串的字符A和主串中的坏字符对齐,进行下一轮比较:

 

640.png

 

接下来,我们继续逐个字符比较,这次发现全部字符都是匹配的,比较公正完成:

640.png640.jpg640.jpg640.png640.jpg640.jpg

//在模式串中,查找index下标之前的字符是否和坏字符匹配
private
static
int
 findCharacter
(
String
 pattern
,
char
 badCharacter
,
int
 index
)
{
for
(
int
 i
=
 index
-
1
;
 i
>=
0
;
 i
--){
if
(
pattern
.
charAt
(
i
)
==
 badCharacter
){
return
 i
;
}
}
//模式串不存在该字符,返回-1
return
-
1
;
}
public
static
int
 boyerMoore
(
String
 str
,
String
 pattern
)
{
int
 strLength 
=
 str
.
length
();
int
 patternLength 
=
 pattern
.
length
();
//模式串的起始位置
int
 start 
=
0
;
while
(
start 
<=
 strLength 
-
 patternLength
)
{
int
 i
;
//从后向前,逐个字符比较
for
(
i 
=
 patternLength 
-
1
;
 i 
>=
0
;
 i
--)
{
if
(
str
.
charAt
(
start
+
i
)
!=
 pattern
.
charAt
(
i
))
//发现坏字符,跳出比较,i记录了坏字符的位置
break
;
}
if
(
i 
<
0
)
{
//匹配成功,返回第一次匹配的下标位置
return
 start
;
}
//寻找坏字符在模式串中的对应
int
 charIndex 
=
 findCharacter
(
pattern
,
 str
.
charAt
(
start
+
i
),
 i
);
//计算坏字符产生的位移
int
 bcOffset 
=
 charIndex
>=
0
?
 i
-
charIndex 
:
 i
+
1
;
        start 
+=
 bcOffset
;
}
return
-
1
;
}
public
static
void
 main
(
String
[]
 args
)
{
String
 str 
=
"GTTATAGCTGGTAGCGGCGAA"
;
String
 pattern 
=
"GTAGCGGCG"
;
int
 index 
=
 boyerMoore
(
str
,
 pattern
);
System
.
out
.
println
(
"首次出现位置:"
+
 index
);
}

640.jpg640.jpg好后缀规则


 

“好后缀” 又是什么意思?就是指模式串和子串当中相匹配的后缀。

让我们看一组新的例子:

640.png

对于上面的例子,如何我们继续使用“坏字符规则”,会有怎样的效果呢?

从后向前比对字符,我们发现后面三个字符都是匹配的,到了第四个字符的时候,发现坏字符G

 

640.png

 

接下来我们在模式串找到了对应的字符G但是按照坏字符规则,模式串仅仅能够向后挪动一位:

640.png

 

这时候坏字符规则显然并没有起到作用,为了能真正减少比较次数,轮到我们的好后缀规则出场了。由于好后缀规则的实现细节比坏字符规则要难理解得多,所以我们这里只介绍一个大概思路:

 640.png

我们回到第一轮的比较过程,发现主串和模式串都有共同的后缀“GCG”,这就是所谓的“好后缀”。

如果模式串其他位置也包含与“GCG”相同的片段,那么我们就可以挪动模式串,让这个片段和好后缀对齐,进行下一轮的比较:

 

640.png

 

显然,在这个例子中,采用好后缀规则能够让模式串向后移动更多位,节省了更多无谓的比较。

640.jpg640.png640.jpg640.png640.jpg640.jpg640.jpg640.jpg640.jpg640.jpg


相关文章
|
5天前
|
机器学习/深度学习 存储 算法
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
近端策略优化(PPO)是深度强化学习中高效的策略优化方法,广泛应用于大语言模型的RLHF训练。PPO通过引入策略更新约束机制,平衡了更新幅度,提升了训练稳定性。其核心思想是在优势演员-评论家方法的基础上,采用裁剪和非裁剪项组成的替代目标函数,限制策略比率在[1-ϵ, 1+ϵ]区间内,防止过大的策略更新。本文详细探讨了PPO的基本原理、损失函数设计及PyTorch实现流程,提供了完整的代码示例。
108 10
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
|
1月前
|
算法 数据可视化 安全
基于DWA优化算法的机器人路径规划matlab仿真
本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。
147 68
|
1天前
|
算法
基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
本程序基于海鸥优化算法(SOA)进行三维曲面最高点搜索的MATLAB仿真,输出收敛曲线和搜索结果。使用MATLAB2022A版本运行,核心代码实现种群初始化、适应度计算、交叉变异等操作。SOA模拟海鸥觅食行为,通过搜索飞行、跟随飞行和掠食飞行三种策略高效探索解空间,找到全局最优解。
|
3天前
|
传感器 算法 物联网
基于粒子群算法的网络最优节点部署优化matlab仿真
本项目基于粒子群优化(PSO)算法,实现WSN网络节点的最优部署,以最大化节点覆盖范围。使用MATLAB2022A进行开发与测试,展示了优化后的节点分布及其覆盖范围。核心代码通过定义目标函数和约束条件,利用PSO算法迭代搜索最佳节点位置,并绘制优化结果图。PSO算法灵感源于鸟群觅食行为,适用于连续和离散空间的优化问题,在通信网络、物联网等领域有广泛应用。该算法通过模拟粒子群体智慧,高效逼近最优解,提升网络性能。
|
3天前
|
机器学习/深度学习 数据采集 算法
基于GWO灰狼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a,展示了时间序列预测算法的运行效果(无水印)。核心程序包含详细中文注释和操作视频。算法采用CNN-GRU-SAM网络,结合灰狼优化(GWO),通过卷积层提取局部特征、GRU处理长期依赖、自注意力机制捕捉全局特征,最终实现复杂非线性时间序列的高效预测。
|
1月前
|
机器学习/深度学习 数据采集 算法
基于GA遗传优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a实现时间序列预测,采用CNN-GRU-SAM网络结构。卷积层提取局部特征,GRU层处理长期依赖,自注意力机制捕捉全局特征。完整代码含中文注释和操作视频,运行效果无水印展示。算法通过数据归一化、种群初始化、适应度计算、个体更新等步骤优化网络参数,最终输出预测结果。适用于金融市场、气象预报等领域。
基于GA遗传优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
|
1月前
|
移动开发 算法 计算机视觉
基于分块贝叶斯非局部均值优化(OBNLM)的图像去噪算法matlab仿真
本项目基于分块贝叶斯非局部均值优化(OBNLM)算法实现图像去噪,使用MATLAB2022A进行仿真。通过调整块大小和窗口大小等参数,研究其对去噪效果的影响。OBNLM结合了经典NLM算法与贝叶斯统计理论,利用块匹配和概率模型优化相似块的加权融合,提高去噪效率和保真度。实验展示了不同参数设置下的去噪结果,验证了算法的有效性。
|
1月前
|
算法 决策智能
基于SA模拟退火优化算法的TSP问题求解matlab仿真,并对比ACO蚁群优化算法
本项目基于MATLAB2022A,使用模拟退火(SA)和蚁群优化(ACO)算法求解旅行商问题(TSP),对比两者的仿真时间、收敛曲线及最短路径长度。SA源于金属退火过程,允许暂时接受较差解以跳出局部最优;ACO模仿蚂蚁信息素机制,通过正反馈发现最优路径。结果显示SA全局探索能力强,ACO在路径优化类问题中表现优异。
|
1月前
|
传感器 算法
基于GA遗传优化的WSN网络最优节点部署算法matlab仿真
本项目基于遗传算法(GA)优化无线传感器网络(WSN)的节点部署,旨在通过最少的节点数量实现最大覆盖。使用MATLAB2022A进行仿真,展示了不同初始节点数量(15、25、40)下的优化结果。核心程序实现了最佳解获取、节点部署绘制及适应度变化曲线展示。遗传算法通过初始化、选择、交叉和变异步骤,逐步优化节点位置配置,最终达到最优覆盖率。
|
1月前
|
算法
基于RRT优化算法的机械臂路径规划和避障matlab仿真
本课题基于RRT优化算法实现机械臂路径规划与避障。通过MATLAB2022a进行仿真,先利用RRT算法计算避障路径,再将路径平滑处理,并转换为机械臂的关节角度序列,确保机械臂在复杂环境中无碰撞移动。系统原理包括随机生成树结构探索空间、直线扩展与障碍物检测等步骤,最终实现高效路径规划。