串匹配算法讲解 -----BF、KMP算法
参考文章:
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算法的更多相关文章
- 算法起步之kmp算法
[作者Idlear 博客:http://blog.csdn.net/idlear/article/details/19555905] 这估计是算法连载文章的最后几篇了,马上就要 ...
- 算法笔记之KMP算法
本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...
- 字符串匹配(BF算法和KMP算法及改进KMP算法)
#include <stdio.h> #include <string.h> #include <stdlib.h> #include<cstring> ...
- 常用算法3 - 字符串查找/模式匹配算法(BF & KMP算法)
相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟 ...
- 串的两种模式匹配方式(BF/KMP算法)
前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最重要的操作之一,而不同的算法实现有着不同的 ...
- 第4章学习小结_串(BF&KMP算法)、数组(三元组)
这一章学习之后,我想对串这个部分写一下我的总结体会. 串也有顺序和链式两种存储结构,但大多采用顺序存储结构比较方便.字符串定义可以用字符数组比如:char c[10];也可以用C++中定义一个字符串s ...
- 算法(贪心|BF|KMP)
贪心算法 前置知识 const Greedy = num => { //贪心 let arr = [100, 20, 10, 5, 2, 1] let count = 0; for (let i ...
- 问题 1690: 算法4-7:KMP算法中的模式串移动数组
题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...
- 迷宫城堡+算法讲解【tarjian算法】
Tarjan 算法 参考博客:https://www.cnblogs.com/shadowland/p/5872257.html 算法讲解 Tarjan 算法一种由Robert Tarjan提出的求解 ...
随机推荐
- XeLaTeX插入GB/T 7714-2005规范的参考文献方法
GB/T 7714-2005 biblatex 在使用XeLaTeX的过程中,会遇到参考文献需要按照GB/T 7714-2005规范的情况.此时需要使用biblatex宏包,并且指定包的参数为 ...
- Leetcode 476.数字的补数
数字的补数 给定一个正整数,输出它的补数.补数是对该数的二进制表示取反. 注意: 给定的整数保证在32位带符号整数的范围内. 你可以假定二进制数不包含前导零位. 示例 1: 输入: 5 输出: 2 解 ...
- J2ee项目 编译依赖顺序
这儿有个帖子, 最后一个回复是: “我把我项目的libraries的"Order and Export"中的JRE与J2EE顺序换了一个问题解决”. 帖子地址: http://b ...
- 静态方法,Arrays类,二维数组
一.静态方法 静态方法属于类的,可以直接使用类名.方法名()调用. 静态方法的声明 访问修饰符 static 类型 方法名(参数列表) { //方法体 } 方法的作用:一个程序分解成几个方法,有利于快 ...
- 基于 K8S 构建数据中心操作系统
在 12 月 22 日 ECUG 的下午场 ,七牛云容器计算部技术总监袁晓沛为大家带来了主题为<基于 K8S 的 DCOS 之路>的精彩分享,向大家介绍了七牛容器云目前 K8S 的状况和产 ...
- 【bzoj4080】[Wf2014]Sensor Network 随机化
题目描述 魔法炮来到了帝都,除了吃特色菜之外,还准备去尝一尝著名的北京烤鸭.帝都一共有n(1<=1<=100)个烤鸭店,可以看成是二维平面内的点.不过由于魔法炮在吃烤鸭之前没有带钱,所以吃 ...
- 【Luogu】P3521ROT-Tree Rotations(线段树合并)
题目链接 神奇的线段树合并qwq 不过就思路而言很好想…… 观察到一棵树无论怎么交换两棵左右子树,子树内部的最优逆序对并没影响……决策只影响左右子树之间的逆序对…… 于是线段树合并直接乱搞就好啦 ...
- 飞行员配对方案问题(匈牙利算法+sort)
洛谷传送门 匈牙利算法+sort 没什么好说的. ——代码 #include <cstdio> #include <cstring> #include <algorith ...
- [luoguP2774] 方格取数问题(最大点权独立集)
传送门 引入两个概念: 最小点权覆盖集:满足每一条边的两个端点至少选一个的最小权点集. 最大点权独立集:满足每一条边的两个端点最多选一个的最大权点集. 现在对网格染色,使得相邻两点颜色不同,之后把两个 ...
- wifi hand
wpa airmon-ng start wlan0airodump-ng -c 6 -w logs wlan0monaireplay-ng -0 5 -a ap'mac -c clink'mac w ...