java实现的kmp算法
package DataStructure; import java.util.ArrayList;
import java.util.List; //KMP算法的实现
//以下代码由freedom结合资料理解写出
public class DMPtest1 {
private int next[] ;
private String target; //主串
private String pattern;//子串
char[] t; //主串字符
char[] p; //子串字符
private static List<Integer> list ; public DMPtest1() {}
public DMPtest1(String pattern,String target) {
this.pattern = pattern;
this.target = target;
p = this.pattern.toCharArray();
t = this.target.toCharArray();
//list = new ArrayList<Integer>(); //初始化一个集合用于保存匹配的子串在主串中的索引
next = this.getNextArray(this.pattern); //接受返回的已经算好的数组 } public void displayNext() {
//打印next数组
for(int i=0;i<next.length; i++) {
System.out.print(next[i]);
} } public List<Integer> getTargetIndex() {
List<Integer> list = new ArrayList<Integer>();
int num=0;
int i = 0;//主串target下标
int j = 0;//子串pattern下标
if(t.length>=p.length) { while(i<t.length) { //因为主串的下标是不变的,只有匹配超过他自己长度就会跳出循环 if(p[j]==t[i]) {
num++; //第一次相等的话那么num清零
j++;
i++; //System.out.println("已经找到一个目标"+j+p.length);
if(j>p.length-1) {//若已经是最后一个数了 list.add(i-j); //把匹配的字符串在主串中位置(第一个字符的索引)添加到list
j=0; //说明一个子串已经匹配完毕
//j已经等于p数组的最后一个下标的下一个下标了
}
}else {
//两字符不匹配的话
//j的新索引直接等于next[j]结论在纸上写着 if(num==0) {
j=0;
//第一次不相等,那么 i 需要自加
i++;
//这种结构要小心,一定要写在下一个if的前面!
} if(num>0) { //说明不是第一次不相等,那么主串下标不用自加
j=next[j];
num=0; } //System.out.println(j);
}
} }else {
System.out.println("模式串必须 大于或等于 主串 !");
}
return list;
} /**
* 1 、该方法 用于返回一个next[]数组,保存的是模式串的相应T{0~j-1}字串的(最长前缀和后缀相同匹配字符的数量)j是模式串的下标
*
* 2 、 pattern是模式字符串,要转化成char[],如你要搜索freedom,就要把freedom,转成f,r,e,e,d,o,m的char类型数组
*
* 3、此方法是用递归的思想实现,可以一眼写出next数组。在后面会给解释!
*
*/
public int[] getNextArray(String pattern) { int next[] = new int[p.length];
next[0] = -1;
int j = 0; //next数组下标
int k = -1; // 用于临时保存next数组的值 //因为next数组求出来后目的是为了求DMP,所以把整个next数组向右平移1,所以第一位普遍是-1,代表没有该字串
//而next[1]=0,因为第二个位置的字串求得是T{0~j-1}的前缀和后缀最长相同值的长度,所以1个字符是空集,这个会在方法体里面实现 //当j给最后一个字符赋完值,就要跳出循环,如果该字符串有8个字符,那么j必须小于8-1
while(j<p.length-1) {
if(k==-1||p[k]==p[j]) {
//如果匹配成功,j,k两下标都要自加,以比较下一个组合是否相等
j++;
k++;
next[j] = k;
} else {
//如果不匹配,那么j依然不动,k取上一个k的值
k = next[k]; //知道k为-1没有匹配值返回0
}
}
return next;
}
public static void main(String args[]) {
DMPtest1 dmp = new DMPtest1("abc","afwefwaefaaaaabcawiefjawoijfeioawjofabc"); //为next数组初始化了
//dmp.displayNext();
list = dmp.getTargetIndex(); //遍历匹配主串,并将索引返回给list
for(int i=0;i<list.size();i++) {
System.out.println("字符串在主串中的位置是"+list.get(i));
} System.out.println("共有 {"+list.size()+"} 个匹配结果"); }
}
java实现的kmp算法的更多相关文章
- 算法(Java实现)—— KMP算法
KMP算法 应用场景 字符串匹配问题 有一个字符串str1 = " hello hello llo hhello lloh helo" 一个子串str2 = "hello ...
- KMP算法-Java实现
目的: 为了解决字符串模式匹配 历程: 朴素模式匹配:逐次进行比较 KMP算法:利用匹配失败得到的信息,来最大限度的移动模式串,以此来减少比较次数提高性能 概念: m:是目标串长度 n:是模式串长度 ...
- 经典KMP算法C++与Java实现代码
前言: KMP算法是一种字符串匹配算法,由Knuth,Morris和Pratt同时发现(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.比 ...
- 大话数据结构(十二)java程序——KMP算法及改进的KMP算法实现
1.朴素的模式匹配算法 朴素的模式匹配算法:就是对主串的每个字符作为子串开头,与要连接的字符串进行匹配.对主串做大循环,每个字符开头做T的长度的小循环,直到成功匹配或全部遍历完成为止. 又称BF算法 ...
- Java实现KMP算法
/** * Java实现KMP算法 * * 思想:每当一趟匹配过程中出现字符比较不等,不需要回溯i指针, * 而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远 * 的一段 ...
- [转]KMP算法理解及java实现
这大概是我看的最好懂的KMP算法讲解了,不过我还只弄懂了大概思想,算法实现我到时候用java实现一遍 出处:知乎 https://www.zhihu.com/question/21923021/ans ...
- KMP算法中next数组的理解与算法的实现(java语言)
KMP 算法我们有写好的函数帮我们计算 Next 数组的值和 Nextval 数组的值,但是如果是考试,那就只能自己来手算这两个数组了,这里分享一下我的计算方法吧. 计算前缀 Next[i] 的值: ...
- Java数据结构之字符串模式匹配算法---KMP算法2
直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...
- Java数据结构之字符串模式匹配算法---KMP算法
本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...
随机推荐
- 深入了解linux下的last命令及其数据源
http://www.9usb.net/200902/linux-last.html http://blog.csdn.net/chaofanwei/article/details/11826567
- JAVA IO 类库详解
JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...
- 深入理解javascript:揭秘命名函数表达式
这是一篇转自汤姆大叔的文章:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 前言 网上还没用发现有人对命名函数表达式进去重复深 ...
- 【poj1006-biorhythms】中国剩余定理
http://poj.org/problem?id=1006 题意:中国剩余定理的裸题. 题目可转化为求最小的x满足以下条件: x%23=a;x%28=b;x%33=c; 关于中国剩余定理可看我昨天的 ...
- UNIX网络编程——网络IPC:套接字
UNIX网络编程——网络IPC:套接字 Contents 套接字接口 套接字描述符 寻址 字节序 地址格式 地址查询 绑定地址 建立连接 数据传输 套接字选项 带外数据 UNIX域套接字 使用套接字的 ...
- Spring框架学习之第3节
model层(业务层+dao层+持久层) spring开发提倡接口编程,配合di技术可以更好的达到层与层之间的解耦 举例: 现在我们体验一下spring的di配合接口编程,完成一个字母大小写转换的案例 ...
- CentOS7安装配置Apache HTTP Server
RPM安装httpd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # yum -yinstall http ...
- Java:多线程
创建线程的方式有两种: 第一种:使用线程类Thread或者继承它的子类创建线程对象 第二种:定义接口类实现接口Runnable创建线程对象 多线程的好处:可以整合资源,提高系统资源的利用率 多线程中提 ...
- USACO Section 3.1: Stamps
这题一开始用了dfs(注释部分),结果TLE,后来想了DP方法,f[i] = f[j] + f[i-j], j = 1, 2... i/2, 还是TLE,网上搜了别人的代码,发现自己的状态方程有问题, ...
- dojo 资源库
文档 :http://wenku.baidu.com/link?url=Nnek_tAjIC-Q3t3e9zHQmsh4LhU3f0ncC1QH8WD_U9-I8-fJ7mMisscFpgfuS8nU ...