模式匹配算法

2023-11-16

下面分别介绍:朴素模式匹配算法 改进模式匹配算法(KMP)

朴素模式匹配算法思想:

从目标S中的第一个字符开始和模式T中的的第一个比较(用  i  和 j 分别指示S串和T串中正在比较字符的位置),若相等,则继续逐个比较后续字符,否则, 从S 的第二字符重新开始匹配,直到匹配完成。

核心就是 i = i - j +1 ;  //其中 j 就是已经匹配字符的个数 。+1 带表下一次匹配的位置。

///朴素匹配
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int Index(char S[],char T[]){
    int i,j;
    i=0;j=0;
    int lens=strlen(S);
    int lent=strlen(T);
   // cout<<lent<<" "<<lens;
  while(i<lens&&j<lent){
    if(S[i]==T[j]){
        i++;
        j++;
    }
    else{
        i=i-j+1;///然现在T串已经匹配了j 的长度,所以直接将 i 回退 j 个长度
        j=0;
    }
  }
  if(j=lent-1)///T 已经匹配结束,然后S 串中的起始位置
    return i-lent;
  else
    return -1;
}
int main()
{
    char S[10000]="afdfsdgdfbsderre";
    char T[10000]="dgdf";
    cout<<Index(S,T)<<endl;
    return 0;
}

 

改进模式匹配算法(KMP)

时间复杂度O(n +  m)

它的改进之处:每一趟匹配过程中出现字符比较不相等时,不需要回溯  i 值 ,而是利用已经的 “ 部分匹配” 的结果将 T(模式)向右 “滑动” 尽可能远的一段距离后在进行比较。 (用通俗的讲: 就是现在不需要将 i 值往会移动, 而是将 T(模式串) 往右移动。具体移动到到哪里就根据next[] 数组的值确定 )

下面介绍如何求解模式串的next 数组值:

根据当位置的前 一个串 的 前缀和后缀串的最多匹配字符个数 //例如当前位置是 j  , 就看 0 ~ j-1  这个串的前后缀最多匹配字符数

需要补充的是:0~j-1 这个串的前缀和后缀分别是 1~j-1   和 0~j-2  (意思就是前缀部包括第一个字符, 后最不包括最后一个字符)

求解以前: 自己需要根据题目要求, 设定 next 的起始位置的值, 有的是 0 , 有的则是 以1 ; 具体就看 字符串的起始位置。

下面介绍next 索引 从0 开始

例如: abaabaac   

首先 next[0] =0;

求 next[1] 的值得的时候, 我们就看 0~0    显然前缀和后缀串都是空串 所以是 0 

next[1] =0;

求 next[2] 的值得的时候, 我们就看 0~1   显然前缀1~1和后缀串 0~0 ; 显然不匹配 所以

next[2]=0;

同理 next[3]=0;

求 next[4]  的值得的时候, 我们就看 0~3   显然前缀1~3和后缀串 0~2 ; 显然t[3]==t[0] =='a'

next[4]=1;

后面的依次类推。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Maxsize =10000;
void Get_next(char T[],int(&next)[Maxsize]){///next 的索引从0开始,获取next数组
    int i=0,j=-1;
    next[0]=-1;///初始化
    int len =strlen(T);
    while(i<len){
        if(j==-1||T[j]==T[i]){
            ++i;
            ++j;
            next[i]=j;///
        }
        else
            j=next[j];
    }
}
void Get_nextval(char T[],int (&nextval)[Maxsize],int next[]){///获取nextval
    int j=0;
    nextval[0]=-1;///初始化
    int len =strlen(T);
    for(j=1;j<len;j++){
        if(T[next[j]]==T[j])
            nextval[j]=nextval[next[j]];
        else
            nextval[j]=next[j];
    }
}
int Index(char S[],int next[],char T[]){///进行模式匹配
    int i=0,j=0;
    int len =strlen(S);
     int lent =strlen(T);
    while(i<len&&j<lent){
        if((j==-1)||(S[i]==T[j])){
            i++;
            j++;
        }
        else
            j=next[j];
    }
    if(j==lent)
        return i-lent;
    else
        return -1;
}
int main()
{
     int next[Maxsize];
     int nextval[Maxsize];
     char S[Maxsize]="afdfsdgdfbsderre";
     char T[Maxsize]="bsder";
     Get_next(T,next);
     Get_nextval(T,nextval,next);
     cout<<Index(S,next,T)<<endl;///通过next数组匹配获取位置信息
     cout<<Index(S,nextval,T)<<endl;///通过nextval数组匹配获取位置信息
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模式匹配算法 的相关文章

随机推荐

  • KNN实现手写数字识别

    其他实现手写数字识别的方法 1 聚类 K means 实现手写数字识别 2 卷积神经网络 CNN 实现手写数字识别 3 全连接神经网络实现手写数字识别 4 聚类 K means 实现手写数字识别 2 实验数据是老师收集了所有人的手写数字图片
  • jeesite快速开发平台(一)----简介

    以下内容来自官网 一 平台简介 JeeSite是基于多个优秀的开源项目 高度整合封装而成的高效 高性能 强安全性的开源Java EE快速开发平台 JeeSite是您快速完成项目的最佳基础平台解决方案 JeeSite是您想学习Java平台的最
  • 寄存器的基本原理

    参考大神博客 https blog csdn net qq 37340753 article details 80935423 https blog csdn net u012493828 article details 53439226
  • kali工具的使用

    一 netcat简介与使用 nc的全称为NetCat 它能够建立并接受传输控制协议 TCP 和用户数据报协议 UDP 的连接 Netcat可在这些连接上读写数据 直到连接关闭为止 它可以通过手工或者脚本与应用层的网络应用程序或服务进行交互
  • openblas 第二弹: openblas Android版调用和编译

    1 编译 如果需要在Android下使用openblas 则需要编译Android版本的openblas a文件进行调用 1 openblas的编译时主要参考链接 参考链接一 参考链接二 具体细节太久了 已经忘了 下面是编译好的时候的环境变
  • Linux中普通用户和ROOT用户对Java JDK的配置

    Linux中对对各种工具文件不需要想Windows中似的 还要先一步一步的安装 有的还需要配置环境变量 比如Windows对Java的安装过程 在Linux中 使用指令 tar zxvf 文件名 注意空格 解压完 tar gz 文件 或使用
  • Spring事务实现原理

    Spring事务的原理是基于AOP实现的 所以流程也可以理解为与AOP一样分为3步 解析切面 织入通知和运行时增强 1 解析切面 Srping事务的是通过 EnableTransactionManagement注解开启的 该注解往IoC容器
  • 【逆向】使用CE查找Android中变量的偏移

    0x00 准备工作下载Cheat Engine以及调试器服务端 https www cheatengine org index php 夜神模拟器 https www yeshen com 下载安装贪婪洞窟 梦境模式 http a 4399
  • 【华为OD机试】路灯照明问题 (C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 题目描述 在一条笔直的公路上安装了N个路灯 从位置0开始安装 路灯之间间距固定为100米 每个路灯都有
  • oracle修改块大小设置,oracle性能调整(1)

    1调整数据库服务器的性能Oracle数据库服务器是整个系统的核心 它的性能高低直接影响整个系统的性能 为了调整Oracle数据库服务器的性能 主要从以下几个方面考虑 1 1Oracle 调整操作系统以适合Oracle数据库服务器运行数据库服
  • 利用PicGo+Gitee配置图床

    引言 配置图床 方便我们的使用 比如 我们利用typora写的笔记 直接把发送给别人也可以正常使用 不再会有由于本地图片 而加载不出来图片的情况 此外 图片文件遗失亦可以正常加载出来 因为图片已上传 这里已 Typora Gitee Pic
  • java String(一)—— Java中的String类型

    一 需要理解的代码 import java lang reflect Array import java util ArrayList import java util Arrays import java util HashMap imp
  • DNS服务器正向/反向解析配置

    第四次作业 题目 配置DNS正反向解析 一 正向解析 1 装包 2 配置服务 3 配置服务器 4 测试 1 yum install bind y 2 vim etc named conf 监听53号端口 访问的是本机ip 129 168 2
  • c++命名空间

    命名空间 主要解决全局变量的冲突 内部不允许私有变量 所有变量都是公有的 namespace data int x 10 data x 为域作用符 直接使用等同于使用全局变量 不存在就是0 不包含匿名命名空间内变量 同一个文件引用stati
  • 相见恨晚的办公插件合集(二)

    之前有分享过一些办公的插件 如不坑盒子 打工人插件 易用宝等 下面就简单的介绍一下上面的几个神器后再补充一些其它办公神器吧 不坑盒子 word wps 这是一个非常好用的插件工具 专门应用在Word文档和wps 支持Office 2010以
  • 拓数派入选中国信通院 “铸基计划”「高质量数字化转型产品及服务全景图」

    7 月 27 日 由中国信息通信研究院 以下简称 中国信通院 主办的 2023 数字生态发展大会 暨中国信通院 铸基计划 年中会议在京召开 本次大会深度展示了中国信通院在数字化领域的工作成果 并正式发布了 高质量数字化转型产品及服务全景图
  • GUI基础知识

    GUI编程 1 简介 图形用户界面 Graphical User Interface 又称图形用户接口 是指采用图形方式显示的计算机操作用户界面 GUI的核心技术 AWT Swing 2 Awt 2 1 AWT简介 AWT Abstract
  • springboot报错Could not autowire. No beans of ‘RedisConnectionFactory‘ type found

    这个报错提示是因为springboot升级到2 6 9以后版本就会出现 报错界面 其实上面报错不影响程序使用 但是总是觉得别扭 提供3种解决方式 第一种方案 springboot版本降到2 6 9或以下 第二种方案 通过idea设置不提示该
  • Unity&Webform(2):自定义LifetimeManager和TypeConverter使Unity从HttpContext中取值注入WebForm页面...

    上一篇 Unity WebForm 1 自定义IHttpHandlerFactory使用Unity对ASP NET Webform页面进行依赖注入中让Unity和WebForm结合在一起 通过使用HttpHandlerFactory实现了对
  • 模式匹配算法

    下面分别介绍 朴素模式匹配算法 和 改进模式匹配算法 KMP 朴素模式匹配算法思想 从目标S中的第一个字符开始和模式T中的的第一个比较 用 i 和 j 分别指示S串和T串中正在比较字符的位置 若相等 则继续逐个比较后续字符 否则 从S 的第