字符串匹配算法 之BF、KMP
示例:
1. 已知字符串str1="acabaabaabcacaabc",求str2="abaabcac"是否在字符串str1中?
2. DNA病毒检测。已知患者DNA序列求病毒DNA序列是否在患者DNA中出现过?病毒DNA为环状结构(即首尾相连)。
此文以问题1为例进行解答。
一、BF算法:
即暴力检测法,从字符串第一个字符开始和匹配字符串进行比较如果不同,则从字符串第二个位置开始比较直到结束。
BF算法思想很简单,直接列出代码实现:
static void Main(string[] args)
{
string str = "acabaabaabcacaabc";//"aaabaaaaaab";
string mo = "abaabc";//"aaaab";int flag;//表示查询结果
flag = BF(str, mo, );
if (flag != -) Console.WriteLine("匹配成功!" + " 下标为: " + flag);
else Console.WriteLine("匹配失败!");
}
private static int BF(string str, string mo, int v)
{
int i = v ,j = ;
while (i < str.Length && j < mo.Length)
{
if (str[i] == mo[j])
{
i++;
j++;
}
else
{
i = i - j + ;
j = ;
}
}
if (j >= mo.Length) return i - mo.Length;
else return -;
}
二、KMP算法:
如图:

在检测中发现i和j标记的元素不同,此时如果是BF算法直接ii= i-j+1,j = 0.但是KMP算法思想是让i下标不变,j下标变化,即可以理解为数组str2右移尽可能少的单位。
问题来了,如何知道要移动多少呢?

如图,我们可以知道,在数组str2中j下标之前的所有元素都和数组str1的对应位匹配,那么我们只要保证,将str2数组向右移动k,使得在str2中j=k元素之前的元素依旧匹配即可。因此引入
前缀和后缀的概念,前缀:元素的真子集 ,后缀:元素的反向真子集。即如aba三个元素,最长前缀为ab,最长后缀为ba。但是只有前缀a和后缀a相同所以str2的第四个元素的
next值为1;也就是当匹配到str[3]不同于str1时,此时j下标变为1即str2向右移动到j==下标1。
为此我们只需要根据str2得到next数组就行。即得到str2的最大匹配前后缀个数。默认a[0]=0;即变化值为next值-1.因为next值是在字符串下标从1开始,我们开发通常下标从0开始

代码如下:
static void Main(string[] args)
{
string str = "acabaabaabcacaabc";//"aaabaaaaaab";
string mo = "abaabc";//"aaaab";
int[] next=new int[mo.Length];
int flag;//表示查询结果
setNext(mo, next);
foreach (var item in next)
{
Console.Write(item + " ");
}
Console.WriteLine();
flag = KMP(str, mo, , next);
if (flag != -) Console.WriteLine("匹配成功!" + " 下标为: " + flag);
else Console.WriteLine("匹配失败!");
}
private static void setNext(string mo, int[] next)
{
int i = , j = -;
next[] = -;
while (i < mo.Length - )
{
if (j == - || mo[i] == mo[j])
{
i++; j++;
next[i] = j;
}
else j = next[j];
}
}
private static int KMP(string str, string mo, int v,int[] next)
{
int i = v, j = ;
while (i < str.Length && j < mo.Length)
{
if (j==- || str[i] == mo[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j >= mo.Length) return i - mo.Length;
else return -;
}
//进一步对next数组优化
private static void setNextVal(string mo, int[] next)
{
int i = , j = -;
next[] = -;
while (i < mo.Length-)
{
if (j == - || mo[i] == mo[j])
{
i++; j++;
if (mo[i] != mo[j]) next[i] = j;
else next[i] = next[j];
}
else j = next[j];
}
}
字符串匹配算法 之BF、KMP的更多相关文章
- 字符串匹配算法之BF(Brute-Force)算法
BF(Brute-Force)算法 蛮力搜索,比较简单的一种字符串匹配算法,在处理简单的数据时候就可以用这种算法,完全匹配,就是速度慢啊. 基本思想 从目标串s 的第一个字符起和模式串t的第一个字符进 ...
- 常用算法3 - 字符串查找/模式匹配算法(BF & KMP算法)
相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟 ...
- 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)
1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...
- Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化
1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...
- 数据结构学习之字符串匹配算法(BF||KMP)
数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 编写出BF暴力匹配.KM ...
- 数据结构- 串的模式匹配算法:BF和 KMP算法
数据结构- 串的模式匹配算法:BF和 KMP算法 Brute-Force算法的思想 1.BF(Brute-Force)算法 Brute-Force算法的基本思想是: 1) 从目标串s 的第一个字 ...
- 字符串匹配算法 - KMP
前几日在微博上看到一则微博是说面试的时候让面试者写一个很简单的字符串匹配都写不出来,于是我就自己去试了一把.结果写出来的是一个最简单粗暴的算法.这里重新学习了一下几个经典的字符串匹配算法,写篇文章以巩 ...
- KMP单模快速字符串匹配算法
KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...
- 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现
一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...
随机推荐
- 华为鸿蒙系统pk安卓系统
Harmony OS Vs Android Comparison It isn’t based on Linux kernel The key difference between HarmonyOS ...
- idea 项目 版本控制文件
- 我是如何在四年时间里,从厨师转行为 Serverless 应用开发者
▎本文系译文,我的软件开发入行经历非常有趣 -- 我一开始其实是厨师. 作者:KieranMcCarthy 译者:Aceyclee 我在高中时就喜欢烹饪和烘焙,用不同食材的搭配去做出美味的食物,就像个 ...
- Amsterdam Distance
题目描述 Your friend from Manhattan is visiting you in Amsterdam. Because she can only stay for a short ...
- ckeditor+ckfinder添加水印。
1.修改ckfinder文件下面的config.php:添加一句include_once "plugins/watermark/plugin.php";//水印配置文件 2.修改p ...
- [LC] 59. Spiral Matrix II
Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral ord ...
- be accustomed to doing|actual |acute|adapt |
Sometimes you've got to play a position that you're not accustomedto for 90 minutes, " he said. ...
- StringTokenizer(字符串分隔解析类型)
java.util.StringTokenizer 功效:将字符串以定界符为界,分析为一个个的token(可理解为单词),定界符可以自己指定. 1.构造函数. 1. StringTokenizer( ...
- [LC] 62. Unique Paths
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- 吴裕雄--天生自然python学习笔记:Python3 输入和输出
输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数. 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用. 如果你希望输出的 ...