参考文章:

http://www.matrix67.com/blog/archives/115    

KMP算法详解

http://blog.csdn.net/yaochunnian/article/details/7059486 

 

1、算法的思想

相比蛮力算法,KMP算法预先计算出了一个next数组,用来指导在匹配过程中匹配失败后尝试下次匹配的起始位置,以此避免重复的读入和匹配过程。这个next数组被叫做“部分匹配值表(**Particial match table**)”,它的设计是算法精妙之处。

对BF算法(每次S、T串都回溯)进行改进,尽量利用已经部分匹配的结果信息,尽量让 i 不回溯,加快模式串的滑动速度。

形象地说,就是假如第i+1个字符匹配失败之后,下一个可能匹配位置至少应该往后挪动多少。

2、部分匹配值表

要理解部分匹配值表,就得先了解字符串的前缀(prefix)和后缀(postfix)。

前缀:除字符串最后一个字符以外的所有头部串的组合。

后缀:除字符串第一个字符以外的所有尾部串的组合。

部分匹配值:一个字符串的前缀和后缀中最长共有元素的长度。

举例说明:字符串ABCAB

前缀:{A, AB, ABC, ABCA}

后缀:{BCAB, CAB, AB, B}

部分匹配值:2 (AB)

而所谓的部分匹配值表,则为模式串的所有前缀以及其本身的部分匹配值。

还是针对字符串ABCAB,它的部分匹配值表为:

A B C A B

0 0 0 1 2

 

 

啰嗦几句BF算法:

源码如下:包括BF,和KMP。串匹配算法:

   1:  // BF.cpp : 定义控制台应用程序的入口点。
   2:  //
   3:   
   4:  #include "stdafx.h"
   5:  #include "string"
   6:  #include <iostream>
   7:  using namespace std;
   8:   
   9:   
  10:  int index(string s,string t) /*求模式串t在主串s中的定位函数*/
  11:  { 
  12:      int  i,j,m,n;
  13:      i = 0; 
  14:      j = 0;
  15:      n = s.length(); 
  16:      m = t.length();
  17:     while((i<n)&&(j<m))
  18:     {
  19:         if (s[i]== t[j])   
  20:         {
  21:             i++;
  22:             j++;//可以认为是字符匹配成功的次数
  23:         }
  24:         else  
  25:         {
  26:             i = i - j + 1;//可以认为是S当中每次比较的初始位置
  27:             j = 0;
  28:         }
  29:     }
  30:   
  31:    if ( j>=m ) 
  32:        return i - m + 1;
  33:     else   
  34:        return  -1;
  35:  }
  36:   
  37:   
  38:  int  kmp(string s, string t,int next[]) 
  39:  {
  40:      int  i,j,m,n;
  41:      i = 0; 
  42:      j = 0;
  43:      n = s.length(); 
  44:      m = t.length();
  45:      while((i<n) && (j<m)) //循环控制条件
  46:      {
  47:          if (s[i]== t[j])   //如果两者相等,比较下一个字符
  48:          {
  49:             i++;
  50:             j++;
  51:          }
  52:          else               //否则,j = next[j];
  53:          {
  54:             j = next[j];
  55:          }
  56:      }
  57:      
  58:      if ( j >= m ) //匹配成功,此时j的下标大于等于m
  59:          return i - m + 1;//返回匹配的起始下标
  60:      else   
  61:          return  -1;
  62:      
  63:  }
  64:   
  65:  void  kmpNext(string str,int next[]) 
  66:  {
  67:      next[1]  = 0;
  68:      int j = 1;
  69:      int k = 0;
  70:      while(j < str.length()) 
  71:       {
  72:          if ((k==0) || (str[j-1]==str[k-1])) //第一次匹配或者匹配成功,当t(k)==t(j)
  73:          {
  74:              j++;
  75:              k++;         //继续匹配下一个字符
  76:              next[j] = k;  //相当于next[j] = k + 1;
  77:          }
  78:          else
  79:              k = next[k];  //当t(k)!=t(j),将next[k]给k,然后回溯
  80:       }
  81:  }
  82:   
  83:   
  84:  int main()
  85:   
  86:  {
  87:      string Str,Tsr;
  88:   
  89:      int next[1000]={0,};
  90:      cout <<"请输入S串与T串:" <<endl;
  91:      cin >> Str >> Tsr;
  92:      cout << endl;
  93:      //int flag = index(Str,Tsr);
  94:   
  95:      kmpNext(Tsr,next);
  96:      int  flag =  kmp(Str,Tsr,next);
  97:      if (flag == -1)
  98:      {
  99:          cout << "没有找到子串"<<endl;
 100:      }
 101:      else
 102:      {
 103:          cout << "找到子串的位置为"<< flag <<endl;
 104:      }
 105:   
 106:   
 107:      return 0;
 108:  }
 109:   

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

串匹配算法讲解 -----BF、KMP算法的更多相关文章

  1. 算法起步之kmp算法

    [作者Idlear  博客:http://blog.csdn.net/idlear/article/details/19555905]            这估计是算法连载文章的最后几篇了,马上就要 ...

  2. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  3. 字符串匹配(BF算法和KMP算法及改进KMP算法)

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

  4. 常用算法3 - 字符串查找/模式匹配算法(BF & KMP算法)

    相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟 ...

  5. 串的两种模式匹配方式(BF/KMP算法)

    前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最重要的操作之一,而不同的算法实现有着不同的 ...

  6. 第4章学习小结_串(BF&KMP算法)、数组(三元组)

    这一章学习之后,我想对串这个部分写一下我的总结体会. 串也有顺序和链式两种存储结构,但大多采用顺序存储结构比较方便.字符串定义可以用字符数组比如:char c[10];也可以用C++中定义一个字符串s ...

  7. 算法(贪心|BF|KMP)

    贪心算法 前置知识 const Greedy = num => { //贪心 let arr = [100, 20, 10, 5, 2, 1] let count = 0; for (let i ...

  8. 问题 1690: 算法4-7:KMP算法中的模式串移动数组

    题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...

  9. 迷宫城堡+算法讲解【tarjian算法】

    Tarjan 算法 参考博客:https://www.cnblogs.com/shadowland/p/5872257.html 算法讲解 Tarjan 算法一种由Robert Tarjan提出的求解 ...

随机推荐

  1. 设计模式之单例模式 Singleton实现

    饿汉式 饿汉式单例模式,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题.虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题, 因此可以省略synchronized关 ...

  2. javascript学习笔记 - 引用类型 RegExp

    四 RegExp 格式: var expression = / pattern / flags; 1.flags 为标志.分别为g.i.m. g:表示全局模式.即模式将匹配所有的字符串,而不是在发现第 ...

  3. Oracle 用户和权限

    Oracle 用户和权限Oracle 中,一般不会轻易在一个服务器上创建多个数据库,在一个数据库中,不同的项目由不同的用户访问,每一个用户拥有自身创建的数据库对象,因此用户的概念在 Oracle中非常 ...

  4. HLG2179 组合(dfs水水更健康)

    组合 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 57(38 users) Total Accepted: 43(36 users) ...

  5. hibernate框架的搭建与简单实现增删改

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  6. 前端CSS规范大全(转)

    一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用U ...

  7. [CODEVS1911] 孤岛营救问题(分层图最短路)

    传送门 吐槽:神tm网络流... 用持有的钥匙分层,状态压缩,用 2 进制表示持有的钥匙集合. dis[i][j][k] 表示持有的钥匙集合为 k,到达点 (i, j) 的最短路径. 分层图的最短路听 ...

  8. 刷题总结:排序机械臂(石室中学oj)(splay)

    题目: 题目描述 为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂.它遵循一个简单的排序规则,第一次操作找到最低的物品位置 P1,并把从左起第 1 个至第 P1 个之间的物品反序 ...

  9. 【HNOI2011/bzoj2337】XOR和路径

    第二道高斯消元练习题 题意 一张无向图,从点 $1$ 出发每次随机选一条出边走,走到 $n$ 停止,求经过的所有边权异或和的期望. $n\le 100$ 题解 注意一点,异或和的期望 $≠$ 期望的异 ...

  10. python - opencv 的一些小技巧备忘

    python - opencv 的一些小技巧备忘 使用python-opencv来处理图像时,可以像matlab一样,将一幅图像看成一个矩阵,进行矢量操作,以加快代码运行速度. 下面记录几个常用的操作 ...