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也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
随机推荐
- CMakeList 编写规则 -1
CMAKE 常见指令 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(XXX) SET(CMAKE_BUILD_TYPE Release) SET(CMAKE_ ...
- .Net多线程 并行编程(三)---并行集合
为了让共享的数组,集合能够被多线程更新,我们现在(.net4.0之后)可以使用并发集合来实现这个功能. 而System.Collections和System.Collections.Generic命名 ...
- iOS.Compiler
1. 在Xcode4.6下创建的工程, 在Xcode5下build&run, 然后提示以下error. 难不成要在Xcode5下重新创建工程? Xcode cannot run using t ...
- 怎样完整地离线更新并升级基于 Debian 的操作系统
不久之前我已经向你展示了如何在任意离线的 Ubuntu 和 Arch Linux 操作系统上安装软件. 今天,我们将会看看如何完整地离线更新并升级基于 Debian 的操作系统. 和之前所述方法的不同 ...
- Executor(二)ThreadPoolExecutor、ScheduledThreadPoolExecutor 及 Executors 工厂类
Executor(二)ThreadPoolExecutor.ScheduledThreadPoolExecutor 及 Executors 工厂类 Java 中的线程池类有两个,分别是:ThreadP ...
- part1:4-linux快速体验
1.Linux部分目录结构介绍 /:根目录,一般根目录下只存放目录,尽量不要存放文件:/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中. /bin:可执行二进制文件目录, ...
- MySQL 的IFNULL()、ISNULL()和NULLIF()函数
参考与http://blog.csdn.net/xingyu0806/article/details/52080962 IFNULL(expr1,expr2) 假如expr1不为NULL,则 IFNU ...
- HDU 2161 Primes (素数筛选法)
题意:输入一个数判断是不是素数,并规定2不是素数. 析:一看就很简单吧,用素数筛选法,注意的是结束条件是n<0,一开始被坑了... 不说了,直接上代码: #include <iostrea ...
- HDU 1847 Good Luck in CET-4 Everybody! (博弈)
题意:不用说了吧,都是中文的. 析:虽说这是一个博弈的题,但是也很简单的,在说这个题目前我们先说一下巴什博弈定理. 巴什博弈定理:一堆物品有n个,有两个人(两个人足够聪明)轮流取,规定每次至少取一个, ...
- php读取用友u8采购入库单列表及详细
<?php class erpData { protected static $erp; public function __construct() { $dbhost ="192.1 ...