什么叫做模式匹配呢?其实就是看字符串S中是否有子串T,那么T就叫匹配串。
我们平时查找方式是逐个匹配,那么时间复杂度就是O(n*m).
比如s=’abcabde’,t=’abd’
那么比较的时候s[1]=t[1],所以接下来比较s[2]和t[2],结果s[2]=t[2],那么接下来就比较s[3]和t[3],这一次比较匹配不上。
然后就是普通匹配方法比较耗时的地方:比较s[2]和t[1]继续上面那样的流程。这样就可以看到,最坏的情况需要比较O(n*m)次。
画一下匹配过程:
1 abcabde
   abd      匹配失败
2 abcabde
    a        匹配失败
3 abcabde
      a      匹配失败
4 abcabde
        abd 匹配成功
我们看到比了4次。那么怎么用程序来实现呢?

function CommonIndex(const Sub,Dest:string):Integer ;
vari,j:Integer;Len1,Len2:Integer;
beginLen1:=Length(Sub);Len2:=Length(Dest);Result:=0;if Len1>Len2 thenExit;j:=1;i:=1;//判断过程while (I<= Len2 - Len1 + 1)and(J <= Len1) doif Dest[J] = Sub[I] thenbeginInc(I);Inc(J);endelsebeginJ:=1;     //sub回溯I:=I-J+2; //Dest回溯end;//判断是否查找成功if J = Len1 thenResult:=I-J+1;
end;

接下来看看C怎么实现的:

int CommonIndex(char* sub,char* dest){int i=0,j=0;while (dest[i]&&sub[j]){if (dest[i]==sub[j]){++i;++j;}else{j=0;i-=j-1;}}//endwhileif (!sub[j])return i-j+1;elsereturn 0;
}

就像上面注释那样,每次匹配失败的话,都需要把两个字符串都回溯,所以这里就必要浪费时间了。
整个算法的时间复杂度是O(m*n)
我们再回来看看上面的匹配过程。
1 abcabde
   abd      匹配失败
在匹配到c和d这里,我们发现不用再去比较b和a 以及c和a了,因为肯定不能匹配。所以现在我们只需要回溯sub字符串。
看看改进后的匹配过程:
1 abcabde
   abd      匹配失败
2 abcabde
       abd  匹配成功
但是Sub每次匹配失败后回溯多少呢?这就是这个KMP算法里面精髓的地方。
我们先看看代码吧!

function KMPIndex(const Sub,Dest:String):Integer;
vari,j:Integer;len1,len2:Integer;next:array of Integer;procedure MakeNext;//自过程生产Next表begini:=1;j:=0;next[1]:=0;while i<=len1 doif(j=0)or (sub[i]=sub[j])thenbeginInc(i);Inc(j);next[i]:=j;endelsej:=next[j];end;
beginlen1:=Length(sub);len2:=Length(Dest);Result:=0;if len1>len2 thenExit;SetLength(next,len1 + 1); //动态数组是从0开始的,我们要从1开始,所以这里+1,多一个元素//生成Sub的回溯表。MakeNext;tryi:=1;j:=1;while (i<=len1)and(j<=len2) doif (i=0)or(Sub[i] = Dest[j]) then  //匹配成功begininc(i);Inc(j);endelsei:=next[i]; //失败,只有Sub回溯一下if i > len1 thenResult:=j - i + 1;finallySetLength(next,0);end;
end;

那么C的代码会是怎么样呢?

int KMPIndex(char* sub,char* dest){int len = 0;//计算sub的长度for(;sub[len];++len);//动态分配next数组int* next = (int*)malloc(len *sizeof(int));//生成next数组int i = 0,k = -1;//*(next++) = 0;next[0] = -1;while (i<len)if (k==-1||sub[i]==sub[k]){++i;++k;//*(next++ )= k;next[i] = k;}else{k = next[k];}//现在next数组生成了 ,接下来就是匹配比较了。i = 0;k = 0;while (dest[i]&&sub[k]){if (k==-1||dest[i] ==sub[k]){++i;++k;}elsek=next[k];}//endwhile//比较完了释放next空间free(next);//判断是否匹配成功if (!sub[k])return i - k + 1;elsereturn 0;
}

我们看看时间复杂度吧。理论来说应该大于O(n+m),小于O(n*m).在实际过程中近似O(n+m).
从上面的代码中我们可以看见next的第i个元素是靠比较第i-1个得到的。

while (i<len)if (k==-1||sub[i]==sub[k]){++i;++k;//*(next++ )= k;next[i] = k;}else{k = next[k];}
while i<=len1 doif(j=0)or (sub[i]=sub[j])thenbeginInc(i);Inc(j);next[i]:=j;endelsej:=next[j];

如果字符是从1开始的,那么next[0] = 0,如果字符从0开始的,那么next[0]=-1;
那么我们手动来计算一下 'abababd’的next数组字,假设字符串从1开始。
a b a b a b d
0  //第一个直接等于0
0 1 //第二个要靠第一个去判断。第一个字符为a,对应next[1]值为0,那么结束比较。next[2]=1
0 1 1 //第三个要靠第二个去判断。第二个字符为b,对应的k值为1,而第一个字符是a,由于b不等于a,继续取第一个字符a对应的k值,k为0比较结束,next[3]=1;
0 1 1 2 //第四个要靠第三个。第三个字符是a,对应的k值为1,而第一个字符是a,由于a=a,比较结束next[4]=1+1=2
0 1 1 2 3 //第五个要靠第四个。第四个字符是b,对应k值是2,而第二个字符是b,由于b=b,比较结束next[5]=2+1=3
0 1 1 2 3 4 //同理。第五个字符是a,对应的k值是3,而第三个字符是a,由于a=a,比较结束,所有next[6] = 3+1 = 4;
0 1 1 2 3 4 5 //第六个字符是b,对应的k是4,而第四个字符是b,由于b=b,比较结束,所以next[7] = 4 + 1 = 5;
整个next数组就是 0 1 1 2 3 4 5
不知道大家对上面这个求的过程看明白了没有。
当然这个生成next的过程在特殊情况是有错误的。所以就有了改进的地方,nextval。这个我们下回再说。有条件的朋友可以自己看看书。
书中自有黄金屋,书中自有颜如玉。
金钱与女人都出自书本。。。哈哈,难怪古代文人那么喜欢逛青楼。。。蛋疼。!!
等着我的nextval 谢谢

数据结构 - 字符串的模式匹配相关推荐

  1. 字符串的模式匹配 (朴素模式匹配算法 ,KMP算法)

    字符串的模式匹配 寻找字符串p在字符串t中首次出现的起始位置 字符串的顺序存储 typedef struct {char str[MAXSIZE];int length; }seqstring; 朴素 ...

  2. 字符串的模式匹配(Java实现)

    字符串的模式匹配 字串的定位操作通常称做模式匹配,是各种串处理系统中最重要的操作之一.本文主要介绍两种常用的实现算法: 1.暴力匹配 2.KMP算法 1.暴力匹配 时间复杂度为O(n*m):n为主串长 ...

  3. 算法训练二(字符串、模式匹配、堆栈、队列)(含解题思路)(上)

    目录 7-1 好前缀 AC代码: 7-2 好后缀 AC代码: 7-3 [模板]KMP字符串匹配 AC代码: 7-5 接话茬 AC代码: 7-6 串的模式匹配 AC代码: 7-7 词频统计 AC代码: ...

  4. 浅谈python高级数据结构—— 字符串(str)

    浅谈python高级数据结构-- 字符串(str) 在python中字符串可以说的运用的特别多了.在当我们input 输入的时候,也是一个str字符串类型,我们今天就来简单的说一下(字符串)类型的一些 ...

  5. 数据结构——字符串和多维数组

    本章节主要内容: 字符串存储 模式匹配 数组的逻辑结构特征 数组的存储方式及寻址方法 特殊矩阵和稀疏矩阵的压缩存储方法 一.字符串 1.串:零个或多个字符组成的有限序列. 串长度:串中所包含的字符个数 ...

  6. 数据结构-------字符串和多维数组

    本章节主要内容: 字符串存储 模式匹配 数组的逻辑结构特征 数组的存储方式及寻址方法 特殊矩阵和稀疏矩阵的压缩存储方法 一.字符串 1.串:零个或多个字符组成的有限序列. 串长度:串中所包含的字符个数 ...

  7. 数据结构字符串模式匹配中计算next和nextval的值(C语言)

    在KMP模式匹配中通过next的值可以快速达到匹配目的,那next的值怎么计算呢? 其实计算next的值本身也就是对模式串进行模式匹配,我们一起看看计算next的值的过程: 当模式串 P=" ...

  8. 0x00000005 3.数据结构和算法 基础数据结构 字符串(上)

    文章目录 基本知识简单总结 模式匹配 最长回文子串 前缀匹配 扩展和补充* C++11常见API References: 字符串也是一个高频考察点. 虽然可以和数组考点合并,但由于该场景许多优化空间大 ...

  9. 0x15.基本数据结构 — 字符串 (KMP算法(含详细证明)和最小表示法)

    目录 一.KMP模式匹配 1.引理: 2.引理证明: 3.使用优化的算法计算nextnextnext数组: 4.luogu P3375 [模板]KMP字符串匹配 5.UVA1328 Period 6. ...

  10. 字符串的模式匹配,KMP算法

    KMP算法是模式匹配的一种改进的算法,所谓的模式匹配也就是对于两个字符串主串S和模式串T.从主串的S的pos个字符起和模式串中的第一个字符进行比较,如果相等,则继续比较后面的字符,否则从主串的下一个字 ...

最新文章

  1. Soft robotics:造仿生昆虫机器人柔性骨骼新技术,只需2小时,成本不到7块!
  2. swift. 扩展类添加属性_swift中的声明关键字详解
  3. 快速定位Product assignment block里对应的修改逻辑使用的function module
  4. JSP/Servlet中的汉字编码问题
  5. 股市红涨绿跌色系定义真的是中国特色吗?
  6. 前端学习(1608):react-router-dom基础
  7. postgresql 集合类型_PostgreSQL 分组集合新功能(GROUPING SETS,CUBE,ROLLUP)
  8. Ubuntu 16.04下使用apt 搭建 ELK
  9. python爬取公众号,用最简单的方式爬虫
  10. ”十六“进制查看器(转)
  11. 网络/Network - 应用层 - HTTP - GET 通过 Body 来发送数据 - 学习/实践
  12. 没Switch也能玩有氧拳击 咕咚智能运动手表F4全面评测
  13. Rabbit基础概念
  14. 写在NPL小书出版之时
  15. 此战成硕,我成功上岸西南交通大学了~~~
  16. layui 带按钮的搜索框_layui table可输入关键字搜索下拉框(select)
  17. mAPI(商户用API) v1.1发布
  18. 武汉Uber优步司机奖励政策
  19. nodeJS的环境搭建以及nodeJS和npm简介
  20. 使用大白菜制作U盘启动器并安装win10 64位系统

热门文章

  1. python中tkinter模块_Python模块:tkinter
  2. 性能可靠服务器虚拟化,服务器虚拟化分析
  3. java runnable 匿名_Java 开发者最困惑的四件事
  4. python中capital是什么意思_Capital是什么意思?
  5. 流程图函数’怎么画_程序员必备画图技能之——流程图
  6. boot客户管理系统源码_开源 SpringBoot+vueJs 前后端管理系统模版
  7. 计算十进制转为二进制后1的个数
  8. 【2019-1期 QFC素质拓展活动】圆满结束
  9. CentOS系统安装FTP服务器
  10. app.honeycomb.Shell$HomeActivity failed to start