字符串模式匹配,即子串的定位操作。就是判断主串S中是否存在给定的子串,如果存在,那么返回子串在S中的位置,否则返回0。
实现这种操作有两种算法:

朴素的模式匹配算法

设主串S长度为n,子串T长度为m。

思路
 对于主串的每个字符,做长度为$strlen(T)$的循环,判断是否与子串匹配。
 最好的情况就是一开始就匹配成功,时间复杂度O(1);
 最坏的情况就是每次匹配失败都是在T的最后一个元素,复杂度O(n*m);
 平均情况复杂度O(n + m)。
 int match(string s, string t) {
if (t.size() > s.size())
return -; int i = , j = ;
while (i < s.size() && j < t.size()) {
if (t[j] == s[i]) {
++i;
++j;
}
else {
i = i - j + ;
j = ;
}
} if (j == t.size())
return i - j;
else
return -;
}

KMP算法

思路
KMP主要分两步:
 1. 进行T的自匹配
这一步关键在于得到Next数组,从T的第一位开始对自身匹配,在某一位置能匹配的最长长度即是当前位置Next值。
Next中的值是字符串的前缀集合与后缀集合的交集中最长元素的长度,将Next[0] = -1。
举例来说:T=ababaca,前缀为pre,后缀为post。
i = 1: 要处理"a", pre = "", post = "", Next[1] = 0;
i = 2: 要处理"ab", pre = a, post = b, Next[2] = 0;
i = 3: 要处理"aba", pre = {a, ab}, post = {ba, a}, Next[3] = 1;
i = 4: 要处理"abab", pre = {a, ab, aba}, post = {bab, ab, b}, Next[4] = 2;
i = 5: 要处理"ababa", pre = {a, ab, aba, abab}, post = {baba, aba, ba, a}, Next[5] = 3;
......
Next数组{-1,0,0,1,2,3,0,1}
 2. S与T的匹配
这步的匹配和朴素匹配没有太大差异,只是主串S的指针不用回溯,而将子串的指针j回溯到Next[j]位置。
 void nextCompute(string t, vector<int>& next) {
int i = , j = -;
while (i < t.size()) {
if (j == - || t[i] == t[j]) {
++i;
++j;
next[i] = j;
}
else {
j = next[j];
}
}
} int KMP(string s, string t) {
vector<int> next(t.size() + , -);
nextCompute(t, next); int i = , j = ;
while (i < (int)s.size() && j < (int)t.size()) {
if (j == - || s[i] == t[j]) {
++i;
++j;
}
else {
j = next[j];
}
} if (j == t.size())
return i - j;
else
return -;
}

改进KMP算法

主要改进了Next数组。

 /*计算next数组*/
void next_compute(char T[], int* next)
{
int i = , j = -;
next[] = -;
while (i < strlen(T))
{
if (- == j || T[i] == T[j]) //自匹配
{
i++;
j++;
if (T[i] != T[j])
next[i] = j;
else
next[i] = next[j];
}
else //字符不同,j值回溯
{
j = next[j];
}
}
}

Pattern Matching的更多相关文章

  1. Beginning Scala study note(5) Pattern Matching

    The basic functional cornerstones of Scala: immutable data types, passing of functions as parameters ...

  2. Symbols of String Pattern Matching

    Symbols of String Pattern Matching in Introduction to Algorithms. As it's important to be clear when ...

  3. scala pattern matching

    scala语言的一大重要特性之一就是模式匹配.在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中, ...

  4. Zhu-Takaoka Two-dimensional Pattern Matching

    Two dimensional pattern matching. Details may be added later.... Corresponding more work can be foun ...

  5. [PureScript] Break up Expressions into Cases in PureScript using Simple Pattern Matching

    Pattern matching in functional programming languages is a way to break up expressions into individua ...

  6. [Scala] Pattern Matching(模式匹配)

    Scala中的match, 比起以往使用的switch-case有著更強大的功能, 1. 傳統方法 def toYesOrNo(choice: Int): String = choice match ...

  7. pattern matching is C# 7.0

    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is 原来的版本 private static s ...

  8. C#9.0 终于来了,带你一起解读Pattern matching 和 nint 两大新特性玩法

    一:背景 1. 讲故事 上一篇跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客园和公号里的阅读量都达到了新高,甚是欣慰,不管大家对新特性是多 ...

  9. 函数式编程之-模式匹配(Pattern matching)

    模式匹配在F#是非常普遍的,用来对某个值进行分支匹配或流程控制. 模式匹配的基本用法 模式匹配通过match...with表达式来完成,一个完整的模式表达式长下面的样子: match [somethi ...

  10. KMP string pattern matching

    The function used here is from the leetcode. Details can be found in leetcode problem: Implement str ...

随机推荐

  1. Docker基础修炼2--Docker镜像原理及常用命令

    通过前文的讲解对Docker有了基本认识之后,我们开始进入实战操作,本文先演示Docker三要素之镜像原理和相关命令. 本文的演示环境仍然沿用上一篇文章在本地Centos7中安装的环境,如果你本地没有 ...

  2. (js描述的)数据结构[链表](4)

    (js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...

  3. Java字符串的应用

    字符串的简单应用 public class join { public static void main (String args[]){ String s1 = new String (" ...

  4. STC15F2K60S2串口通信的应用。

    前言:由于不可抗拒因素,初始的STC12C5A60S2芯片由于无法进行烧录(...因为没带有锁紧座的开发板),暂且使用STC15F2K60S2芯片.. 一 串行通信概述: 串口通信有SPI IIC U ...

  5. 软件包管理rpm和yum

    rpm的使用: 安装的包相关包信息会保存在/var/lib/rpm目录下的文件中 安装参数: -i install安装 -v 显示详细信息 -h 打印####号 -V 校验软件包,会到/var/lib ...

  6. Jenkins 批量创建任务的三种方法

    最近,要搭建多套测试环境,需要把 Jenkins 中 dev 视图下的所有任务批量复制到 sit 等视图下. 说明 Jenkins 任务名称规则为:[测试环境标识]-[工程名称],如:dev-daod ...

  7. stand up meeting 12/7/2015

    part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云  ------------------    --  ---------------------  --- PDF Rea ...

  8. windows批处理protoc生成C++代码

    1 首先需要生成protoc的可执行文件,具体可以参考  https://www.cnblogs.com/cnxkey/articles/10152646.html 2 将单个protoc文件生成.h ...

  9. Laravel joinSub 子查询的写法

    $subQuery = $model::query() ->from('table1 as a') ->getQuery(); $query = $model::query() -> ...

  10. Git把本地代码推送到远程github仓库

    运用Git版本控制系统进行代码的管理,以便于团队成员的协作,由于之前是使用svn来进行版本控制,所以对于Git使用还有待熟练掌握.Git与svn类似,个人认为两者之间比较直观的区别就是 Git 不需要 ...