串的模式匹配(KMP算法)

2023-11-12

【问题描述】

串的模式匹配算法实现(KMP算法)

【输入形式】

第一行输入主串s;

第二行输入模式串t;

第三行输入起始位置pos;

【输出形式】

输出模式串t的next值(以空格分隔)

输出模式匹配结果

【样例输入1】

ababcabcacbab

abcac

1

【样例输出1】

-1 0 0 0 1

6

BF算法的原理简单但效率较低。原因是 i 和 j 的回溯,即在某趟匹配失败后,对于 s 串要回溯到本趟开始字符的下一个字符,t 串要回溯到第一个字符。然而这些回溯很多是不必要的。

  改进的模式匹配过程由Knuth,Morris,Pratt同时设计的,简称KMP算法,其特点是,每当一趟匹配过程中Si和Tj匹配失败后,指针i不动,模式t向右“滑动”,使Tk和Si对准继续向右比较。

比较过程如下:

第一趟比较,主串,子串均从起始位置开始比较,匹配失败时主串 i=2,子串 j=2。

 第二趟比较,主串 i 保持不动,不回溯,子串向前滑动至 j=0的位置,开始对应字符的比较。一直到发生匹配失败时,主串 i=6,子串 j=4。

 

 

 我们将模式串的每个位置匹配失败时滑动的位置计算出来,放到一个 next数组中,当发生匹配失败时直接拿出来用即可,Nex数组的求解过程分三种情况:

这里将 next[0] 设置为-1。

 

 

 

 next数组的计算:

void getNext(SqString *t,int next[]){
    int i=0,j=-1;
    next[0]=-1;
    while(i<t->length)
    {
        if((j==-1)||(t->data[i]==t->data[j]))
        {
            i++;
            j++;
            next[i]=j;
        }
        else j=next[j];
    }
}

KMP算法:

int indexKMP(SqString *s,SqString *t,int start,int next[]){
    int i=start-1,j=0;
    while(i<s->length&&j<t->length)
    {
        if(i==-1||s->data[i]==t->data[j])   //*s 和 t 对应字符相等,比较下一个字符
    {
        i++;
        j++;
    }
    else j=next[j];     //开始下一次匹配,子串指针 j 移动到下一个比较位置
    }

    if(j>=t->length)
        return(i-t->length);
    else
        return 0;
}

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

#define INITSIZE 1000
#define INCRE 20
#define OK 1
#define ERROR 0

typedef struct{
  char* data;
  int length,stringsize;
}SqString;

//串初始化
int initString(SqString *S){
    S->data=(char *)malloc(INITSIZE*sizeof(char));
    if(!S->data)
        return ERROR;
    S->length=0;
    S->data[0]='\0';
    S->stringsize=INITSIZE;
    return OK;
}

//串赋值
int strAssign(SqString *s, char *str ){
    int i=0;
    while(*str!='\0')
        s->data[i++]=*str++;
    s->data[i]='\0';
    s->length=i;
    return OK;
}
//模式匹配KMP算法
int indexKMP(SqString *s,SqString *t,int start,int next[]){
    int i=start-1,j=0;
    while(i<s->length&&j<t->length)
    {
        if(i==-1||s->data[i]==t->data[j])
    {
        i++;
        j++;
    }
    else j=next[j];
    }

    if(j>=t->length)
        return(i-t->length);
    else
        return 0;
}
//求取模式串next值
void getNext(SqString *t,int next[]){
    int i=0,j=-1;
    next[0]=-1;
    while(i<t->length)
    {
        if((j==-1)||(t->data[i]==t->data[j]))
        {
            i++;
            j++;
            next[i]=j;
        }
        else j=next[j];
    }
}

int main(){
//使用KMP算法完成串的模式匹配
    SqString s,t;
    int start,i;
    int next[1000];
    char str[1000];
    initString(&s);
    initString(&t);
    scanf("%s",&str);
    strAssign(&s,str);
    scanf("%s",&str);
    strAssign(&t,str);
    getNext(&t,next);
    scanf("%d",&start);
    for(i=0;i<t.length;i++)
    {
        printf("% d",next[i]);
    }
    printf("\n");
    printf("%d ",indexKMP(&s,&t,start,next));
    return 0;
}

运行结果如下:

 

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

串的模式匹配(KMP算法) 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 微信公众平台开放 9 大高级接口,它有什么意义?

    微信的野心大大的 看看它的9大新接口吧 转自 http www ifanr com 366010 微信刚刚更新公众平台 向服务号开放微信认证 开放 9 大高级接口 增加开发者问答系统 并对微信公众平台的后台管理界面进行改版 其中最受关注的是
  • vmware安装redhat 9

    vmware安装redhat 9 1 镜像文件下载 1 1 镜像文件 2 安装系统 2 1 安装时语言 2 2 安装选项设置 2 2 1 手动磁盘分区 2 2 2 设置root密码 允许通过ssh使用密码方式登录root 2 3 开始安装系
  • 最实用的应急响应笔记思路小结

    0x00 事件应急响应的流程分析 事件整个类型大致归类于 事件表现 信息收集 确认攻击类型 事件追查 修复 1 事件的表现 网站类型 被篡改 信息丢失 乱码等 文件类型 被篡改 丢失 泄露等 系统类型 系统卡顿 CPU爆满 服务宕机等 流量
  • 普通大学生如何拿到大厂offer?敖丙教你一招致胜!

    提到敖丙 大家应该并不陌生 三太子敖丙 CSDN博客大V 时年24岁 曾供职于阿里巴巴 蘑菇街等大厂 专注于Java后端研发领域 公众号 三太子敖丙 主理人 敖丙虽然才24岁 但已有五年的职场经验 并且这五年的职场打拼已帮助其实现了财富自由
  • 最新人机对话工具:GPT4介绍(ChatGPT升级版 支持图片且更智能)

    这里写自定义目录标题 显著提升特点 介绍 能力对比 考试能力 知识水平 语言能力 视觉能力 使用方法指南 今天偶然发现期待已久的GPT 4发布了 比上一版的ChatGPT GPT 3 5 性能还好 最主要是支持图片输入 就增加了很多新的场景
  • LeetCode 每日一题 2022_list

    网页链接 LeetCode 坚持住 小镁铝 2022年1月每日一题记录
  • Zabbix--部署--03--proxy安装--6.0

    Zabbix 部署 03 proxy安装 6 0 1 介绍 1 1 官方安装文档 https www zabbix com cn download 1 2 环境介绍 操作系统 centos7 zabbix版本 6 0 LTS 2 准备工作
  • 循环中调用异步接口获取数据

    前言 遇到这样一个需求 调用接口 返回一个新闻列表 再循环这个新闻列表 用每个新闻的id异步请求这个新闻的视频地址 这就需要在循环里调用接口 如果用for循环 接口还没请求完成 for循环就已经执行完了 所以改成promise去处理 开始
  • 支持可变函数调用的php函数,可变函数 - PHP 7 中文文档

    可变函数 PHP 支持可变函数的概念 这意味着如果一个变量名后有圆括号 PHP 将寻找与变量的值同名的函数 并且尝试执行它 可变函数可以用来实现包括回调函数 函数表在内的一些用途 可变函数不能用于例如 echo php7 function
  • 在数学空间中,物理分辨率可能失去了意义(behind the paper)

    写在前面 2020 01到2021 07于我来说 是非常艰难的两年 所以这段时间一直也没有在CSDN持续整理 转载一些CV知识了 而这期间经历了4 5轮审稿 从nature辗转nature biotechnology 终于把第一篇工作发表了
  • linux服务器安装配置jdk

    1 下载jdk 用wget命令 下载linux对应版本的jdk到 usr local 然后解压 cd usr local wget http download oracle com otn pub java jdk 7u79 b15 jdk
  • [转]Untiy学习 -一个简单的有限状态机(FSM)

    前言 参考资料 unity3D FSM有限状态机 状态设计模式 核心 先列举有限数量的状态 让需要被控制的物体在状态中根据设定流转 并且每次只存在一个状态被激活 三个方案 声明一个enum字典 写入所有的状态 public enum Ene
  • 基于springboot+Thymeleaf的校园二手交易平台(附源码获取链接)

    项目描述 以SpringBoot为项目框架开发的二手交易网站 主要用作个人学习 网站的功能模块有 买家模块 卖家模块 购物车 模块 订单模块 内容管理模块 通过这一系列模块能基本满足二手商品的线上交易 基本功能也全部实现 技术架构 Spri
  • 怎么解密PDF文档?这三款解密方法亲测实用

    在日常办公中 我们经常会接触到PDF文件 有时候为了保护文件不被随意查看编辑 会给PDF文件进行加密操作 但是如果出现特殊情况 需要让其他人进入文档查看 就要对其进行解密 可能还有很多小伙伴不清楚加密的PDF怎么解密 别急 今天我给大家分享
  • top命令学习

    文章目录 一 top命令回显信息含义 1 第一行 2 第二行 3 第三行 4 第四行 5 第五行 6 第六行进程信息 二 top简单交互 1 按数字 1 显示列出所有cpu的信息 2 按 M 按内存使用率从大到小排序 3 按 P 按CPU使
  • linux中源码安装node

    Linux上安装Node js 直接使用已经编译好的包 node 官网已经把linux 下载版本更改为已经编译好的版本了 我们可以直接下载解压后使用 wget https nodejs org dist v14 15 0 node v14
  • 2018年终总结及2019计划

    第一次写总结性的文章 就想到哪写哪吧 1 上半年软考考试 我考的计算机系统集成项目管理工程师 原先公司是对有证书的人每月都有一定的奖励 然后就去考了 哈哈 当时确实是因为奖励 经过几个月断断续续的复习 结果也挺顺利的考过了 2 转战上海 我
  • Nginx篇04-map模块

    nginx的map模块配置语法 map模块是由ngx http map module模块提供的 只能在http模块下使用 nginx默认自带安装 map 的主要作用简单来说就和编程语言中的赋值语句有点像 只不过这里称为映射 map 具体来说
  • 使用python进行文件夹重命名

    import os file name JPEGImages 文件存放地址 count 0 for file in os listdir file name os rename os path join file name file os
  • 串的模式匹配(KMP算法)

    问题描述 串的模式匹配算法实现 KMP算法 输入形式 第一行输入主串s 第二行输入模式串t 第三行输入起始位置pos 输出形式 输出模式串t的next值 以空格分隔 输出模式匹配结果 样例输入1 ababcabcacbab abcac 1