串的模式匹配——KMP && BF

本文详细阐述了KMP算法的核心思想,与BF算法进行了对比,并通过实例代码展示了如何使用KMP算法进行字符串匹配。重点强调了KMP算法在模式匹配过程中的高效性和节省时间的特点。

BF算法匹配的话,确实是最容易想到和实现的,也难怪现在还是广泛应用中,一般情况下,BF算法的效率还是可以的,但是最坏情况下就不行了,KMP算法就解决了这个问题,相应地,当然比BF算法复杂了,一开始看KMP 真的不知道它在说啥,看了几遍才理清思路。

KMP的主要思想(有一些自己的理解):匹配模式T和主串T,在已经匹配了j-1个的情况下,如果现在S[i]和T[j-1]不相等,那么如果是BF算法,就从T[0]重新开始,而且i坐标也要回去,这样就浪费了时间,KMP算法则是从已经匹配的j-1中选择一个位置k,从位置k开始,进行S[i]和T[k]的比较,找出这个k就是KMP的高明和困难之处。

假设现在S[i-1]应该与T中的第k(k<j)个字符继续比较,则模式T中第k个字符之前的k-1个字符必定与主串S中第i个字符之前的k-1个字符相等。

即有 (T[0],T[1],.......,T[k-2])= (S[i-k],S[i-k+1],......,S[i-2])

而已经得到模式T和主串S“部分匹配”的结果是

(T[0],T[1],.....,T[J-K],T[J-K+1],.....T[J-2])=(S[i-j],S[i-j+1],.....,S[i-k],S[i-k+1],.......,S[i-2])

综合上面两个式子,可得(T[0],T[1],......,T[K-2])=(T[J-K],T[J-K+1],.......,T[J-2]);

所以只要找出满足上式的k就可以让,S的第i个字符与模式T的第k个字符开始比较,也就省下了时间。

求K的过程,KMP是用一个next[]的整形数组,这个数组的定义是这样的:

1、当j=0时,next[j]=-1;

2、max{k|0<kj-1 且 T[0],T[1],......,T[K-2])=(T[J-K],T[J-K+1],.......,T[J-2]);}

3、0 其他情况

求解next[j]的方法:

设模式T为"abaabcac"

序号01234567
T[j]abaabcac
k0011201
T[k]与T[j]比较!===!===!===!=
next[j]-10011201

假设现在next[0]~next[4]都已经球出来了,现在要求next[5],求解过程是这样的:

令k=next[4]=1,比较T[4]与T[1],T[4]==T[1],所以next[5]=next[4]+1=k+1=2;

如果要求next[6],那么就令k=next[5]=2,T[5]!=T[2],令k=next[2]=0,T[5]!=T[0],令k=next[0]=-1,此时,当k=-1时,就默认是寻找k的过程结束了,此时就和上面一样,next[6]=next[5]+1=k+1=0;

由上面两个例子可以知道,求解next[j]就是先令k等于next[j-1],然后就是比较T[j-1]与T[k],不想等时,就令k=next[k],如此反复做下去,直到T[j-1]==T[k]或者是k=-1为止,

此时next[j]=k+1;

下面是KMP 和 BF 的代码

文件"mystring.h"

#include<string> using namespace std; //BF算法 int Index_BF(string S,string T,int pos) { //中要满足1<=pos<=S.getlength()-T.getlength()+1 int i=pos-1,j=0; while(S[i+j]!='\0' && T[j]!='\0') { if(S[i+j]==T[j]) j++; else { i++; j=0; } } if(T[j]=='\0') return i; else return -1; } //下面是KMP算法 void Get_next(string T,int next[]) { //求模式T的next函数值并存入数组next中,为后面的模式匹配做准备 int k=-1,j=0; next[0]=-1; int length=T.length(); while(j<length) { if( (k==-1)||(T[j]==T[k]) ) { ++j; ++k; next[j]=k; } else k=next[k]; } } int Index_KMP(string S,string T,int pos,int next[]) { //利用模式T的next函数求模式T在主串S的第pos个字符后面的位置 //其中要满足1<=pos<=S.getlength()-T.getlength()+1 int i=pos-1,j=0; int n=S.length(); int m=T.length(); while(i<n && j<m) { if(j==-1 || S[i]==T[j])//j=-1时,是在T的第一个元素就和S[i]不相等时 { ++i; ++j; } else j=next[j]; } if(j>=m) return i-m;//匹配成功 else return -1;//匹配失败 }


主函数测试"main.cpp"文件

#include"mystring.h" #include<iostream> using namespace std; int main() { string S("wangjikaiailiudan"); string T("liudan"); int next[1024]; memset(next,0,sizeof(next)); Get_next(T,next); int pos1=Index_KMP(S,T,7,next); int pos2=Index_BF(S,T,8); if(pos1==-1 && pos2==-1) cout<<"无法匹配"<<endl; else cout<<"模式T在主窜S的第 "<<(pos1+pos2)/2<<" 号位置开始匹配成功"<<endl; return 0; }


【评估多目标跟踪方法】9个高度敏捷目标在编队中的轨迹和测量研究(Matlab代码实现)内容概要:本文围绕“评估多目标跟踪方法”,重点研究9个高度敏捷目标在编队飞行中的轨迹生成与测量过程,并提供完整的Matlab代码实现。文中详细模拟了目标的动态行为、运动约束及编队结构,通过仿真获取目标的状态信息与观测数据,用于验证和比较不同多目标跟踪算法的性能。研究内容涵盖轨迹建模、噪声处理、传感器测量模拟以及数据可视化等关键技术环节,旨在为雷达、无人机编队、自动驾驶等领域的多目标跟踪系统提供可复现的测试基准。; 适合人群:具备一定Matlab编程基础,从事控制工程、自动化、航空航天、智能交通或人工智能等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于多目标跟踪算法(如卡尔曼滤波、粒子滤波、GM-CPHD等)的性能评估与对比实验;②作为无人机编队、空中交通监控等应用场景下的轨迹仿真与传感器数据分析的教学与研究平台;③支持对高度机动目标在复杂编队下的可观测性与跟踪精度进行深入分析。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注轨迹生成逻辑与测量模型构建部分,可通过修改目标数量、运动参数或噪声水平来拓展实验场景,进一步提升对多目标跟踪系统设计与评估的理解。
本软件实现了一种基于时域有限差分法结合时间反转算法的微波成像技术,旨在应用于乳腺癌的早期筛查。其核心流程分为三个主要步骤:数据采集、信号处理与三维可视化。 首先,用户需分别执行“WithTumor.m”与“WithoutTumor.m”两个脚本。这两个程序将在模拟生成的三维生物组织环境中进行电磁仿真,分别采集包含肿瘤模型与不包含肿瘤模型的场景下的原始场数据。所获取的数据将自动存储为“withtumor.mat”与“withouttumor.mat”两个数据文件。 随后,运行主算法脚本“TR.m”。该程序将加载上述两组数据,并实施时间反转算法。算法的具体过程是:提取两组仿真信号之间的差异成分,通过一组专门设计的数字滤波器对差异信号进行增强与净化处理,随后在数值模拟的同一组织环境中进行时间反向的电磁波传播计算。 在算法迭代计算过程中,系统会按预设的周期(每n次迭代)自动生成并显示三维模拟空间内特定二维切面的电场强度分布图。通过对比观察这些动态更新的二维场分布图像,用户有望直观地识别出由肿瘤组织引起的异常电磁散射特征,从而实现病灶的视觉定位。 关于软件的具体配置要求、参数设置方法以及更深入的技术细节,请参阅软件包内附的说明文档。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值