当前位置: 首页 > wzjs >正文

网站名字要备案吗美食软文300范例

网站名字要备案吗,美食软文300范例,优秀高端网站建设企业,石家庄seo网站推广串字符串匹配与暴力算法 主串与模式串 字符串匹配是计算机科学中最古老、 研究最广泛的问题之一。 一个字符串是一个定义在有限字母表∑上的字符序列。 例如, ATCTAGAGA 是字母表∑ {A,C,G,T}上的一个字符串。 字符串匹配问题就是在一个大的字符串 S 中搜索某个字…

![[Pasted image 20250713032527.png]]

字符串匹配与暴力算法
主串与模式串

字符串匹配是计算机科学中最古老、 研究最广泛的问题之一。
一个字符串是一个定义在有限字母表∑上的字符序列。 例如, ATCTAGAGA 是字母表∑ = {A,C,G,T}上的一个字符串。 字符串匹配问题就是在一个大的字符串 S 中搜索某个字符串 P 的所有出现位置。 在这个问题中, S 又被称为主串, P 又被成为模式串。
![[Pasted image 20250713032617.png]]

暴力算法

一种平凡的思路是模式串和主串从主串起始位置开始匹配, 若发生匹配失败, 则模式串向后移动 1 位再进行比较, 直到匹配成功或主串的每个起始位置都已经被尝试过(匹配失败) 。
![[Pasted image 20250713032650.png]]

如上图中, 对于模式 P = aab 和主串 T = acaabc, 将模式 P 沿着 T 从左到右滑动, 逐个比较字符以判断模式 P 在主串 T 中是否存在。
显然, 假设主串的长度为 n, 模式串的长度 m, 那么显然, 这个算法的时间复杂度为O(nm), 当 m 与 n 同阶时, 复杂度可能达到 O(n²)。

Kmp 算法

求解 next 数组的口诀

  1. 求出模式串的部分匹配值;
  2. 将部分匹配值右移一位;
  3. 在首位字符处补-1;
    注: 若是选择题, 需要观察选项的 next 数组是从-1 开始的还是 0 开始的, 若是从 0 开始的需要将刚才求出的 next 数组中所有的值+1 即可得到答案;
    下面着重讲解部分匹配值的求法;
    先给出相关定义:
    字符串前缀: 字符串最后一个字符之外的所有头部子串;
    字符串后缀: 字符串第一个字符之外的所有尾部子串;
    部分匹配值: 字符串的前缀和后缀的最长相等前后缀长度;
    比如字符串”aabaa”, ’a’的前后缀都是空, ’aa’的前后缀分别是’a’和’a’, 那么此处的部分匹配值就是 1, …, 以此类推, 最后整个字符串的前缀有{a,aa,aab,aaba}后缀有{abaa,baa,aa,a},最长的相等前后缀长度就是 2
    ![[Pasted image 20250713033200.png]]

然后将该部分匹配值表的内容统一右移一位(舍去最右边那一位):
![[Pasted image 20250713033211.png]]

在首位补-1, 即可得到 next 数组:
![[Pasted image 20250713033220.png]]

最终就求得了字符串 aabaa 的 next 表-1,0,1,0,1, 若需要从 0 开始就整体+1, 即 0,1,2,1,2

练习题

主串是 ababbababa,模式串‘ababa’ 的 next 数组是? 在使用 kmp 算法匹配时, 一共发生了几次失配?
![[Pasted image 20250713033525.png]]

![[Pasted image 20250713033540.png]]

失配时模式串指针回退到P[next[j]]P[next[4]] = P[2]
![[Pasted image 20250713033603.png]]

P[next[2]] = P[0]
![[Pasted image 20250713033811.png]]

P[next[0]] = P[-1]
主串和模式串指针都右移一位

kmp算法

失配分析

![[Pasted image 20250713180616.png]]

匹配成功必要条件: T.suffix == T.pre
若T.suffix == T.pre : 直接从S[j]P[j]处开始比较即可
j’的含义:
当模式串P在P[j]处与S[i] 发生失配时,将P[j]移动到与s[j]对齐的位置继续匹配,P右移j-j'长度
在kmp算法中,用next[j]来替换这里的j’

next[j]的含义

![[Pasted image 20250713181102.png]]

![[Pasted image 20250713181118.png]]

![[Pasted image 20250713181134.png]]

![[Pasted image 20250713181148.png]]

![[Pasted image 20250713181213.png]]

显然:
在多个可选的T.pre == T.suffix中,只有选择较长的pre和suffix,才能确保滑动距离最短,满足所有情况。但是,pre和suffix不能取T,否则不能移动

构建next表

![[Pasted image 20250713181252.png]]

next[0]=-1:
P[0]处失配时,需要将P移过当前位置,等效为将P[-1]S[j]对齐。
![[Pasted image 20250713181332.png]]

next[2]=1:
P[2]处失配时,匹配成功部分最长,可重叠前后缀长度为1。
![[Pasted image 20250713181409.png]]

next[3]=0:
匹配成功部分最长,当P[3]处失配时,可重叠前后缀长度为0。
![[Pasted image 20250713181443.png]]

next[4]=1:
P[4]处失配时,匹配成功部分最长,可重叠前后缀长度为1。
![[Pasted image 20250713181513.png]]

next[5]=2:
P[5]处失配时,匹配成功部分最长,可重叠前后缀长度为2。
![[Pasted image 20250713181633.png]]

next[6]=2:
P[6]处失配时,匹配成功部分最长,可重叠前后缀长度为2。
![[Pasted image 20250713181729.png]]

next[7]=3:
匹配成功部分最长,当匹配成功时,可重叠前后缀长度为3。

next[] = [-1,0,1,0,1,2,2,3]
注意:上面的next表数组是从0开始计数的,当数组从1开始计数,需要整体加1:
next[] = [0,1,2,1,2,3,3,4]
考试时根据选项next表第一个元素是-1还是0判断

主算法

![[Pasted image 20250713182001.png]]

失配时:
j = 5 , next[5] = 2,因此j = next[5] = 2
![[Pasted image 20250713182038.png]]

失配时:
j = 5 , next[5] = 2, 因此j = next[5] = 2
![[Pasted image 20250713182111.png]]

继续依次比较,可以匹配成功。

int KMP(char * S,char * T){int next[10];Next(T,next);//根据模式串T,初始化next数组 int i = 0;  //i表示主串指针int j = 0;  //j表示模式串指针while(i < strlen(S) && j < strlen(T)){if(j == -1 || s[i] == T[j]){i++; j++;}else{j = next[j];//如果测试的两个字符不相等,i不动,j变为当前模式串的next值}}if(j >= strlen(T)){//如果条件为真,说明匹配成功return i -(int)strlen(T);} return -1;
}
改进版kmp算法

![[Pasted image 20250713182530.png]]

j=6处发生失配,原因:
P[j] = ‘a’ ≠ S[i]
按朴素kmp算法: j = next[j] = 3
![[Pasted image 20250713182557.png]]

此时发现,P[j]依然等于’a’。 此次匹配注定也是失败的。
因此,若P[next[j]] == P[j],这种替换也是无效的,所以在前面构建next[]表的基础上,还必须加入限制条件:
P[next[j]] ≠ P[j]
![[Pasted image 20250713182636.png]]

nextval[0] = -1:这一点和构建next表方式是一样的
![[Pasted image 20250713182651.png]]

nextval[1] = -1next[0] = 0,但是由于P[0] == P[1],所以不能选用0。
![[Pasted image 20250713182713.png]]

nextval[2] = 1:匹配成功部分为”aa”,因此最长可匹配的前后缀为”a”和”a”,长度为1,且P[1]!=P[2].
![[Pasted image 20250713182736.png]]

nextval[3] = -1:匹配成功部分为”aab”,因此最长可匹配的前后缀为长度为0,且P[0] == P[3],所以不能选用该方案,退而选择nextval[3] = -1
![[Pasted image 20250713182809.png]]

nextval[4] = -1:匹配成功部分为”aaba”,因此最长可匹配的前后缀为“a”和”a”,长度为1,且P[1] == P[4],所以不能选用该方案,又因为P[0] == P[4],所以nextval[4]!=0
![[Pasted image 20250713182839.png]]

nextval[5] = 1:匹配成功部分为”aabaa”,因此最长可匹配的前后缀为“aa”和”aa”,长度为2,又因为P[2] == P[5],所以不能选用该方案,继续寻找备选,次长可匹配前后缀为’a’和’a’,长度为1,而且P[1]!=P[5],所以nextval[5] = 1
![[Pasted image 20250713182910.png]]

nextval[6] = -1:匹配成功部分为”aabaab”,因此最长可匹配的前后缀为“aab”和”aab”,长度为3,又因为P[3] == P[6], 所以不能选用该方案,继续寻找备选,次长可匹配前后长度为0,而且P[0] == P[6],所以nextval[5]!=0,因此nextval[6] = -1

显然,nextval[7] = next[7] = 1

快速构建next表

![[Pasted image 20250713183105.png]]

本质就是找到一个合适的移动距离,使得P的前缀和P的后缀可以匹配
![[Pasted image 20250713183050.png]]

P[j-1] == P[next[j-1]]
![[Pasted image 20250713183138.png]]

next[j] = next[j-1] + 1
![[Pasted image 20250713183205.png]]

P[j-1] != P[next[j-1]]
![[Pasted image 20250713183222.png]]

则继续比较P[j-1]P[next[next[j-1]]

void Next(int* next,char P[])
{int i = 0, j = -1; next[0] = -1;while(i < strlen(P)){if(j == -1 || P[i] == P[j]){next[i + 1] = j+1;i++; j++;}else{j = next[j];}}
}
http://www.dtcms.com/wzjs/231277.html

相关文章:

  • 网站301重定向代码2020国内十大小说网站排名
  • 上海兴业建设有限公司网站seo引擎优化软件
  • 网站添加可信任站点怎么做用asp做的网站
  • 有没有好的网站可以学做头发营销软件网
  • 网站托管平台日本预测比分
  • 网站怎么加载图片做logo宁波seo怎么做引流推广
  • 网站建设经验靠谱的免费建站
  • 大的网站建设公司好免费推广网站排行榜
  • 深圳竞价网站外链工具软件
  • 制作个人网站的步骤网站制作流程
  • 网络客服工作平台有哪些sem和seo是什么职业
  • 做众筹的网站有几个腾讯企点注册
  • 海南省建设网站的公司电话号码青岛网站建设制作
  • 安阳网站开发管理培训
  • 网站工作状态建设知乎关键词排名
  • 定制网站开发接私活域名权重查询
  • 河北邯郸中考成绩查询网站今日的最新新闻
  • 夫妻做网站seo职业规划
  • 电商广告宁波seo网站
  • 网站建设维护方案百度一下浏览器下载安装
  • 做网投网站搜狗搜索引擎网页
  • 西安+医疗网站建设营销顾问公司
  • 众博彩做倍投的网站靠谱吗百度竞价排名是什么意思
  • 手机上传视频网站开发提升网站权重的方法
  • 全网黄页网站精准营销包括哪几个方面
  • 做液压的公司网站江苏seo网络
  • 郑州市人民政府网站优化seo公司哪家好
  • 广西城乡与住房建设厅网站网站制作和推广
  • 网站建设设计设计公司哪家好淘宝权重查询
  • 草桥做网站公司百度贴吧怎么做推广