串的模式匹配

现考虑一个常用操作,在字符串s(我们称为主串)中的第pos开始处往后查找,看在主串s中有没有和子串p相匹配的的,如果有,则返回字串p第一次出现的位置。

暴力求解

int Index(char s[], char p[], int pos)
{
int i=pos,j=0;
while(s[i] != '\0' && p[j] != '\0') /* 没有到达结尾 */
if(s[i] == p[j]) {
i++; j++; /* 如果相等继续比较后面的字符 */
}
else {
i = i-j+1; /* i回到比较起点的后一个 */
j = 0; /* j从新开始 */
} if(p[j] == '\0') /* 匹配成功 */
return i-j; /* 返回成功那次的比较起点 */
else
return -1; /* 返回 -1 代表找不到位置 */
}

KMP算法

相比暴力算法多了一个字串的next映射函数,而该算法的核心和技巧就在于next数组上的求解。

int KmpSearch(char* s, char* p)
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}

next的求解

void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1) {
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k]) {
++k;
++j;
next[j] = k;
}
else {
k = next[k];
}
}
}

或者

//优化过后的next 数组求法
void GetNextval(char* p, int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k]) {
++j;
++k;
//较之前next数组求法,改动在下面4行
if (p[j] != p[k])
next[j] = k; //之前只有这一行
else
//因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,k = next[k] = next[next[k]]
next[j] = next[k];
}
else {
k = next[k];
}
}
}

串的模式匹配,KMP算法的更多相关文章

  1. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  2. 字符串模式匹配——KMP算法

    KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...

  3. 模式匹配KMP算法

    关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...

  4. 模式匹配-KMP算法

    /***字符串匹配算法***/ #include<cstring> #include<iostream> using namespace std; #define OK 1 # ...

  5. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  6. 串的模式匹配——Brute-Force算法

    Brute-Force算法的基本思路为:从目标串s=“s0s1...sn-1”的第一个字符开始和模式串t=“t0t1t2...tn-1”中的第一个字符比较,若相等,则继续逐个比较后续字符: 否则从目标 ...

  7. 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构

    题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...

  8. 字符串匹配算法系列一:KMP算法原理

    本文主要参考了https://mp.weixin.qq.com/s/rbaPmBejID8-rYui35Snrg的表述,加上部分自己的理解 学习任何算法都要了解该算法解决什么问题?我们看看KMP算法主 ...

  9. 详讲KMP算法

    两个字符串: 模式串:ababcaba 文本串:ababcabcbababcabacaba KMP算法作用:快速在文本串中匹配到模式串 如果是穷举法的方式: 大家有发现,这样比效率很低的. 所以就需要 ...

  10. 串的模式匹配和KMP算法

    在对字符串的操作中,我们经常要用到子串的查找功能,我们称子串为模式串,模式串在主串中的查找过程我们成为模式匹配,KMP算法就是一个高效的模式匹配算法.KMP算法是蛮力算法的一种改进,下面我们先来介绍蛮 ...

随机推荐

  1. Monkey测试感想

    monkey测试主要做随机的黑盒测试,通过不断输入伪随机的事件流来测试应用的稳定性,但是由于monkey太过皮,太过随机,最后根本无法控制,很容易陷于一个页面无法出来,或者陷入某个无关紧要的地方无法出 ...

  2. 常使用的VIM命令及文件颜色代表含义

    编辑模式--->输入模式 i : insert 在光标所在处输入: a:append 在光标所在处后面输入: o:在当前光标所在行的下方打开一个新行: I:在当前光标所在行的行首输入: A:在当 ...

  3. Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config

    目录 Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config Spring Cloud Config(二):基于Git搭建配置中心 Spring Cl ...

  4. https证书制作及springboot配置https

    1.生成秘钥 openssl genrsa -out private.key 2048 2.生成用于申请请求的证书文件csr,一般会将该文件发送给CA机构进行认证,本例使用自签名证书 openssl ...

  5. Spring事务知识点

    事务的传播属性 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.// 最常用,@Transactional注解默认 PROPAGA ...

  6. tomcat部署web项目的问题

    1:启动窗口乱码 原因 Tomcat默认都是UTF-8的,但是控制台是GBK的,要保持一致 解决办法 打开tomcat目录下的conf/目录下logging.properties找到java.util ...

  7. 数据分析 - Excel 综合实例 - 杜邦分析法

    项目背景 杜邦分析法 利用 杜邦分析法完成对一份数据的动态分析 流程图如下 项目源数据 左侧为竖向的数据管理, 右侧为横向的数据管理 横向的数据管理在数据透视的时候会很不方便, 并不推荐 常用叫法左边 ...

  8. java.util.concurrent.DelayQueue 源码学习

    jdk1.8 DelayQueue,带有延迟元素的线程安全队列,当非阻塞从队列中获取元素时,返回最早达到延迟时间的元素,或空(没有元素达到延迟时间).DelayQueue的泛型参数需要实现Delaye ...

  9. mac下不允许安装除了app store之外的软件设置:

    1.dock栏的系统偏好设置. 2.找到安全性与隐私 3.点击面板中的通用,在点击左小角的锁按钮, 4.选择任何来源,确定就可以了.[如果只有两个选项,而没有任何来源的话,打开终端,执行:sudo s ...

  10. uni-app 使用Vuex+ (强制)登录

    一.在项目的根目录下新建一个store文件夹,然后在文件夹下新建一个index.js文件 二.在新建的index.js下引入vue和vuex,具体如下: //引入vue和vuex import Vue ...