KMP Demo
The key of Kmp is to build a look up table that records the match result of prefix and postfix. Value in the table means the max len of matching substring that exists in both prefix and postfix. In the prefix this substring should start from 0, while in the postfix this substring should ends at current index.
For example, now we have a string "ababc"
The KMP table will look liks this:
a b a b c
-1 0 1 2(Note: we will not match substring with itself, so we will skip index 0)
So how does this table help us search string match faster?
Well, the answer is if we are trying to match a char after posfix with target string and failed, then we can smartly shift the string, so that the matching string in perfix will replace postfix and now we can try to match the char after prefix with this char in target.
Take above string as an example.
Now we try to match string "ababc" with "abababc".
We will initially have match as below
0 1 2 3 4 5 6a b a b a b c (string x)
a b a b c (string y)
-1 0 1 2We found char at index 4 does not match, then we can use look up table and shift the string y wisely.
We found table[3] = 2, which means we can shift the string y rightward by 2, and still have same but shorter prefix before index 4, like this:
0 1 2 3 4 5 6
a b a b a b c (string x)
a b a b c (string y)
-1 0 1 2If there is a long gap between prefix and postfix, this shift can help us save a lot of time. In the brute force way, we cannot do that because we have no information of the string. We have to compare each possible pair of chars. While in KMP, we know the information of string y so we can move smartly. We can directly jump to the next possible match pairwhile discard useless pair of chars.
We are almost done with KMP, but we still have one special case that needs to be taken care of.
Say now we have a input like this:
0 1 2 3 4 5
a a b a a a
-1 1 0 2 3How should we build the KMP table for this string?
Say the pointer in prefix is 'x', which is at index 2 now and the pointer in postfix is 'y' which is at index 5 now. We need to match 'b' pointed by x with 'a' pointed by y. It is an unmatched pair, how should we update the cell?
Well, we really don't need to reset it to 0, that will make us skip a valid shorter matching substring "aa".
What we do now is just to shorten the length of substring by 1 unit and try to match a shorter substring "aa". This can be done by moving pointer x to the index recorded in [indexOf(x) - 1] while keep pointer y stay still. This is because by following the value in KMP table we can always make sure previous part of prefix and postfix is matched even we have shorten their length, so wo only need to care about the char after matched part in prefix and posfix.
Code: [Java]
// JAVA program for implementation of KMP pattern
// searching algorithm class KMP_String_Matching {
void KMPSearch(String pat, String txt)
{
int M = pat.length();
int N = txt.length(); // create lps[] that will hold the longest
// prefix suffix values for pattern
int lps[] = new int[M];
int j = 0; // index for pat[] // Preprocess the pattern (calculate lps[]
// array)
computeLPSArray(pat, M, lps); int i = 0; // index for txt[]
while (i < N) {
if (pat.charAt(j) == txt.charAt(i)) {
j++;
i++;
}
if (j == M) {
System.out.println("Found pattern "
+ "at index " + (i - j));
j = lps[j - 1];
} // mismatch after j matches
else if (i < N && pat.charAt(j) != txt.charAt(i)) {
// Do not match lps[0..lps[j-1]] characters,
// they will match anyway
if (j != 0)
j = lps[j - 1];
else
i = i + 1;
}
}
} void computeLPSArray(String pat, int M, int lps[])
{
// length of the previous longest prefix suffix
int len = 0;
int i = 1;
lps[0] = 0; // lps[0] is always 0 // the loop calculates lps[i] for i = 1 to M-1
while (i < M) {
if (pat.charAt(i) == pat.charAt(len)) {
len++;
lps[i] = len;
i++;
}
else // (pat[i] != pat[len])
{
// This is tricky. Consider the example.
// AAACAAAA and i = 7. The idea is similar
// to search step.
if (len != 0) {
len = lps[len - 1]; // Also, note that we do not increment
// i here
}
else // if (len == 0)
{
lps[i] = len;
i++;
}
}
}
} // Driver program to test above function
public static void main(String args[])
{
String txt = "ABABDABACDABABCABAB";
String pat = "ABABCABAB";
new KMP_String_Matching().KMPSearch(pat, txt);
}
}
// This code has been contributed by Amit Khandelwal.
Reference:
https://www.geeksforgeeks.org/java-program-for-kmp-algorithm-for-pattern-searching-2/
KMP Demo的更多相关文章
- KMP算法实现
		链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ... 
- kmp算法,求重复字符串
		public class Demo { public static void main(String[] args) { String s1 = "ADBCFHABESCACDABCDABC ... 
- KMP 算法 & 字符串查找算法
		KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ... 
- 【数据结构&算法】10-串基础&KMP算法源码
		目录 前言 串的定义 串的比较 串的抽象类型数据 串与线性表的比较 串的数据 串的存储结构 串的顺序存储结构 串的链式存储结构 朴素的模式匹配算法 模式匹配的定义 朴素的匹配方法(BRUTE FORC ... 
- 通过一个demo了解Redux
		TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ... 
- KMP算法求解
		// KMP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespac ... 
- 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo
		有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ... 
- 在线浏览PDF之PDF.JS (附demo)
		平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#skill 下载地址:http://mozilla.gith ... 
- 简单有效的kmp算法
		以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ... 
随机推荐
- ueditor使用注意
			问题1:后端配置项没有正常加载,上传插件不能正常使用! 我用的是开发版,1.4.3.3 .Net版 网上查了很多,后来发现只是配置的问题而已. 1.在根目录下:config.json 其中有Img上传 ... 
- MSVCR90D.dll
			http://stackoverflow.com/questions/218747/msvcr90d-dll-not-found-in-debug-mode-with-visual-c-2008 I ... 
- MapReduce调优总结与拓展
			本文为<hadoop技术内幕:深入解析MapReduce架构设计与实现原理>一书第9章<Hadoop性能调优>的总结. 图1 Hadoop层次结构图 从管理员角度进行调优 1. ... 
- msys2 设置home路径为windows用户路径
			1配置/etc/nsswitch.conf db_home: windows 2(可不配)增加windows环境变量HOME为%USERPROFILE% 3(可不配)ssh默认仍使用msys中的hom ... 
- hive 报错 java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
			Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable ... 
- css长度
			在CSS样式表中,长度单位分两种: 相对长度单位,如px, em等绝对长度单位,如pt,mm等 CSS相对长度单位(relative length unit) CSS相对长度单位中的相对二字,表明了其 ... 
- jquery ajax请求方式与提示用户正在处理请稍等
			为了提高用户体验度,我们通常会给出 “正在处理,请稍等!”诸如此类的提示.我们可通过设置$.ajax()下的参数beforeSend()来实现 初次使用$.ajax() ,我没有去区分过ajax的异步 ... 
- 使用PrintWriter out=response.getWriter();输出script脚本时乱码解决
			使用PrintWriter out=response.getWriter();输出script脚本时乱码解决 最近遇到了一个奇怪的事情,仅仅用out.print("<script ty ... 
- 2018.09.24 bzoj4977: [[Lydsy1708月赛]跳伞求生(贪心+线段树)
			传送门 线段树好题. 这题一看我就想贪心. 先把a,b数组排序. 然后我们选择a数组中最大的b个数(不足b个就选a个数),分别贪心出在b数组中可以获得的最大贡献. 这时可以用线段树优化. 然后交上去只 ... 
- yum基本操作(转)
			原文地址:http://www.cnblogs.com/chuncn/archive/2010/10/17/1853915.html yum(全称为 Yellow dog Updater, Modif ... 
