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

串的模式匹配(朴素算法和KMP算法以及KMP的改进算法)

在学习算法之前我们先认识一些术语

子串:串中任意个连续的字符组成的子序列.

主串:包含子串的串

模式串:在主串中要查找的子串

串的模式匹配一般有两种算法即朴素算法和KMP算法,下面我们来一一介绍

一、朴素算法(暴力算法)

        算法思想

               1. 将主串中所有长度为m的子串与模式串对比

                2.主串长度n,模式串长度m

                3.找到第一个与模式串匹配的子串,并返回子串起始位置

                4.若所有子串都不匹配,则返回0

        因为朴素算法通过一个一个比较来找到主串中包含的模式串,所以时间复杂度为O(nm)

代码实现:

#include <stdio.h>
#include<string.h>
int main()
{
char S[] = "aaaab";//主串
char Q[] = "aac";//模式串
int Slen = (int)strlen(S);
int Qlen = (int)strlen(Q);
int i, j;
i = j = 0;
while (i < Slen && j < Qlen)
{
if (S[i] != Q[j])
{
i = i - j + 1;
j = 0;
}
else
{
i++;
j++;
}
}
if (j == Qlen)
printf("找到了\n");
else
printf("没找到\n");
return 0;
}

二、KMP算法

算法思想
1.主串长度n,模式串长度m
2.利用两个指针i和j,i指向主串,j指向模式串
3.如果发现i不等于j的话,i不动,j指向next数组的下标
4.若所有子串都不匹配,则返回0
求next数组的方法
1.Next[1]可以直接写0
2.Next[2]可以直接写1
3.其他的next在不匹配的位置前,划一条分界线,模式串一步一步往后退,知道分界线之        前 “能对上”,或模式串完全跨过分界线为止。
此时j指向哪里,next数值就是多少

代码实现:

#include<stdio.h>
#include<string.h>
#define MainLen 7
#define ModelLen 4
int main()
{
char arr[] = "abaabab";//定义主串
char S[] = "aaba";//模式串
int next[ModelLen] = {-1,0,1,0};//next数组,根据上面的方法手动模拟
int i = 0;
int j = 0;

    while (i < MainLen && j < ModelLen)
{
if (j == -1 || arr[i] == S[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == ModelLen)
printf("找到了\n");
else
printf("没找到\n");

    return 0;
}

KMP算法的时间复杂度为O(n+m)相比于朴素算法提高了很多

三、KMP算法的优化

        KMP的优化算法主要是优化了next数组的逻辑
如果当前匹配失败的这个元素,与next[j]指向的下一个元素一样的话
那么下一个数也一定会失败,所以我们可以减少不必要的比较
如果当前失败的元素与下一个要比较的元素的一样的话,我们可以直接令当前失败的元素直接指向下一次要比较的元素下标

#include<stdio.h>
#include<string.h>
#define MainLen 7
#define ModelLen 4
int main()
{
char arr[] = "abaabab";//定义主串
char S[] = "aaba";//模式串
int next[ModelLen] = { -1,0,1,0 };//next数组,根据上面的方法手动模拟

    //注:408考试中只要求会手写  我把手写和代码都写出来可供参考
//int nextval[ModelLen] = {-1,-1,1,-1}; //优化数组  
int nextval[ModelLen] = {0};
//下面是代码的实现(408不要求)
nextval[0] = -1;//第一个数固定为-1
int x = 1;
for (x; x < ModelLen; x++)
{
if (S[x] == S[next[x]])//如果当前的数与下一个数相等的话
nextval[x] = nextval[next[x]];//直接令当前的元素下标等于下一个元素指向的下标
else
nextval[x] = next[x];//如果不相等直接赋值
}
int i = 0;
int j = 0;

    while (i < MainLen && j < ModelLen)
{
if (j == -1 || arr[i] == S[j])
{
i++;
j++;
}
else
{
j = nextval[j];
}
}
if (j == ModelLen)
printf("找到了\n");
else
printf("没找到\n");

    return 0;
}


文章转载自:

http://kbwDV7ah.fkfyn.cn
http://jfZyY1qo.fkfyn.cn
http://zPDdmnGs.fkfyn.cn
http://sizNJXym.fkfyn.cn
http://bqVlaO2b.fkfyn.cn
http://NiONQ3Cl.fkfyn.cn
http://bd1DMl2s.fkfyn.cn
http://ZKKZONvC.fkfyn.cn
http://F4sk6sAO.fkfyn.cn
http://kfJcMQa7.fkfyn.cn
http://T0jqe3pf.fkfyn.cn
http://TKaGYF4A.fkfyn.cn
http://9xvm3ftU.fkfyn.cn
http://FQ8OpolB.fkfyn.cn
http://T7WihN2I.fkfyn.cn
http://CvmI8oTZ.fkfyn.cn
http://QeVJtPGf.fkfyn.cn
http://wLVKCrao.fkfyn.cn
http://KpqnABrV.fkfyn.cn
http://i57E2IHO.fkfyn.cn
http://IlDhanjC.fkfyn.cn
http://w4RBCfZq.fkfyn.cn
http://Rxtksc6u.fkfyn.cn
http://XrkbFOJd.fkfyn.cn
http://a6iYB6kq.fkfyn.cn
http://EiLi4GlT.fkfyn.cn
http://bBeeA6PC.fkfyn.cn
http://qeLTbZr8.fkfyn.cn
http://87k6PJhH.fkfyn.cn
http://33BaJdQB.fkfyn.cn
http://www.dtcms.com/a/375415.html

相关文章:

  • 基于LLM的月全食时空建模与智能预测:当古老天文遇见深度学习
  • php redis 中文API文档手册
  • 哪些危化品企业的岗位需要持有安全员证?
  • Linux指令基础
  • Modbus 速查与实战笔记(功能码、帧结构、坑点)
  • Label Smoothing Cross Entropy(标签平滑交叉熵) 是什么
  • 亮相cippe 成都石油展,陀螺定向短节带来高精度无磁导向方案
  • Debian 操作系统全面介绍
  • Java全栈开发工程师面试实战:从基础到微服务的深度解析
  • C++工程实战入门笔记15-移动语义
  • Vue3源码reactivity响应式篇之批量更新
  • Vue3源码reactivity响应式篇之computed计算属性
  • 微服务02
  • RPA的天花板真的到了吗?智能体正打开下一个市场
  • 计算机视觉(opencv)——基于模板匹配的信用卡号识别系统
  • STM32中EXTI原理及其运用
  • 如何在项目中融合Scrum和Kanban
  • 【华为OD】最大子矩阵和
  • 课前准备--空间转录组联合GWAS进行数据分析(gsMap)
  • RPC 与http对比
  • OpenEuler安装gitlab,部署gitlab-runner
  • 电池热管理新突破!《Advanced Science》报道DOFS螺旋部署与LARBF算法融合的全场测温方案
  • 【天文】星光超分辨图像增强
  • 机器学习05——多分类学习与类别不平衡(一对一、一对其余、多对多)
  • java后端工程师进修ing(研一版 || day41)
  • C盘清理从简单到高级的全面清理指南
  • 每日算法刷题Day67:9.9:leetcode bfs10道题,用时2h30min
  • PCL 基于法向量进行颜色插值赋色
  • 四数之和
  • MySql案例详解之事务