字符串匹配算法 之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核心思想 ...
随机推荐
- Flink(六) —— 配置文件详解
基础配置 #============================================================================== # Common #===== ...
- Flume(二) —— 自定义拦截器、Source、Sink
自定义拦截器 自定义Source 自定义Sink 引入依赖 <dependency> <groupId>org.apache.flume</groupId> < ...
- [LC] 90. Subsets II
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the ...
- GlobalExceptionHandler @ControllerAdvice
package org.linlinjava.litemall.core.config; import org.apache.commons.logging.Log; import org.apach ...
- 吴裕雄--天生自然python学习笔记:python 文件批量处理
Python 在文件处理方面表现突出,关于文件的处理 也是很多人经常用到的功能. 对 Python 的文件处理的技巧进行综合应用,比如把大量文件 的复制.按指定的文件名进行保存.找出重复的照片.将 所 ...
- CSS样式表------第一章:样式表的基本概念
CSS(Cascading Style Sheets,层叠样式表),控制页面样式外观,作用是美化HTML网页. 一. 样式表的基本概念 1.样式表的分类 (1)内联样式表 -----放在元素的开始标 ...
- 895A. Pizza Separation#分披萨问题(前缀和)
题目出处:http://codeforces.com/problemset/problem/895/A 题目大意:对于给出的一些角度的披萨分成两份,取最小角度差 #include<stdio.h ...
- Linux_新建用户
目录 1.新增用户 2.增加密码 新增用户:cn 进入root 输入新建命令 cn就是我们的新的用户名,也可以换成其他的 sudo useradd cn 接下来发现没有反应,是正常的,如图 查看是否新 ...
- Point Estimate|unbiased estimator|Confidence-Interval Estimate
8.1 Estimating a Population Mean Point Estimate estimate a single number, or point. 因为:the mean of ...
- linux系统开机静态分配ip地址
在/etc/sysconfig/network-scripts/ifcfg-eth0文件中 添加: IPADDR=192.168.1.100(设置静态地址) NETMASK=255.255.255.0 ...