7、KMP算法实现--Java代码
来源:互联网 发布:西门子s7300编程手册 编辑:程序博客网 时间:2024/06/04 19:18
KMP算法:
字符串查找问题给定文本串和模式串,从文本串中找出模式串第一次出现的位置。
文本串长度N,模式串长度M:
KMP算法的时间复杂度为O(M+N),空间复杂度为O(M)。
算法程序Java代码:
很多理解写在注释里面了,这里不再累赘,直接看代码和注释就可以了。
package algorithm.basic;/** * KMP算法 * @author baolibin * KMP算法时间复杂度 o(m+n) */public class _02_KMP {public static void main(String[] args) {System.out.println("暴力求解:");String str1="asdasdhhasdasdasd";String str2="dhh";kmp kmps = new kmp(str1,str2);int kmpViolence = kmps.kmpViolence();System.out.println("子串第一个匹配职位下标为:"+kmpViolence);System.out.println("\nKMP求解:");String str3="asdasdhhasdasdasd";String str4="dhh";kmp kmps2 = new kmp(str3,str4);kmps2.printMatch();kmps2.getNext();kmps2.printNext();int judgeKmp = kmps2.judgeKmp();System.out.println("\njudgeKmp="+judgeKmp);}}class kmp{private char[] matchingStr; //匹配串private char[] patternStr; //模式串private int[] next; //next数组public kmp(String matchingStr, String patternStr) {this.matchingStr = matchingStr.toCharArray();this.patternStr = patternStr.toCharArray();this.next=new int[matchingStr.length()];}/** * 暴力求解(Brute Force) * 时间复杂度:o(m*n) * 空间复杂度:o(1) * 子串匹配 */public int kmpViolence(){int i=0,j=0;int patternLen=patternStr.length;int matLen=matchingStr.length-patternLen;while (i<=matLen&&j<patternLen) {if(matchingStr[i+j]==patternStr[j]){ //匹配成功,匹配位置后移j++;}else { //匹配失败,模式串回溯到首位i++;j=0;}}if (j>=patternLen) {//模式串每一位均匹配到,返回匹配首位下标return i;}return -1;}/** * KMP求解 * 时间复杂度:o(m+n) * 空间复杂度:o(m) * 求next数组 * ======================================================= * |K j-1|j * |||||||||||||||||||||||||||||||| * | K | | K | * * 若p[k]=p[j],则 next[j+1]=next[j]+1; * * |K j-1|j * |||||||||||||||||||||||||||||||||||||||||||||| * |h | |h | | K | * | k | * * 若p[k]!=p[j],则h=next[K];若p[h]==p[j],则next[j+1]=h+1; * ======================================================= */public void getNext(){int mLength=matchingStr.length;next[0]=-1;int pre=-1; //next[current-1]int current=0;while (current<mLength-1) { //pre表示前缀,current表示后缀if (pre==-1||matchingStr[current]==matchingStr[pre]) { //若p[k]=p[j],则 next[j+1]=next[j]+1;++pre;++current;next[current]=pre;/* --------------------------------------------------- 优化部分: next[j]=k,若p[j]==p[k],则next[j]可以直接赋值为next[j]==next[k]。 ---------------------------------------------------if (matchingStr[current]==matchingStr[pre]) {next[current]=next[pre];} else {next[current]=pre;}*/} else { //匹配失败时,继续递归计算前缀matchingStr[next(pre)]pre=next[pre]; //若p[k]!=p[j],则h=next[K];若p[h]==p[j],则next[j+1]=h+1;}}}/** * 返回第一个匹配的下标 * 没有匹配成功返回-1 * @return */public int judgeKmp(){int matchLen=matchingStr.length;int patternLen=patternStr.length;int startIndex=-1;int i=0,j=0;while (i<matchLen) {if (j==-1||matchingStr[i]==patternStr[j]) {++i;++j;}/** |i * |||||||||||||||||||||||||||||||||||| next * * | next[i]=k | * | k | | k |i --> t[i] * |||||||||||||||||||||||||||||||||||| 文本串text * * |q * | k |j --> p[j] * |||||||| 模式串pattern * * 若:t[i]!=p[j] * 此时就需要滑动指针j到模式串指定位置开始匹配 * 因为next[i]=k,所以k==j(k为长度,j为下标值),在范围为k的文本串里继续寻求可滑动的最大长度,不断迭代next数组相应的值。 * 若有可滑动的值: * 比如上图存在next[k]=q,则p[q]和t[i]进行比较; * 若没有可滑动的值: * next[k]=0,则模式串从p[0]与t[i]开始比较; */else { //滑动位置,从模式串的指定位置开始与文本串匹配/** * t[i]!=t[k] * 为啥不是j=next[i],因为这就是j==next[i]的比较结果 * 在范围K里面继续寻找可以滑动的位置,k==j,所以next[j]就是next[k]; */j=next[j];}if (j==patternLen) {startIndex=i-patternLen;break;}}return startIndex;}/** * 打印匹配字符串 */public void printMatch(){System.out.print("匹配字符串为: ");for (int i = 0; i < matchingStr.length; i++) {System.out.print(matchingStr[i]+"、");}System.out.print("\n");}/** * 打印next数组 */public void printNext(){System.out.print("next数组为: ");for (int i = 0; i < next.length; i++) {System.out.print(next[i]+"、");}}}
程序运行结果:
1 0
- 7、KMP算法实现--Java代码
- KMP算法-代码实现
- KMP算法代码实现
- KMP算法实现代码
- KMP算法代码实现
- kmp算法java代码
- java实现kmp算法
- KMP算法java实现
- Java实现KMP算法
- KMP算法java实现
- KMP算法----java实现
- KMP算法java实现
- KMP算法Java实现
- KMP 算法 java实现
- Java实现KMP算法
- KMP算法Java实现
- KMP算法java实现
- KMP算法-Java实现
- 关于IE坑爹的hasLayout
- package openjdk-9-jdk 9~b102-1 failed to install/upgrade: trying to overwrite '/usr/lib/jvm/java-9-o
- 环信接收消息本地推送的实现
- Java 获取请求客户端的IP地址
- 前辈们的总结
- 7、KMP算法实现--Java代码
- 设计模式之单例模式
- 树莓派 安装使用 QWT 6.1.3
- Dubbo架构设计详解
- 源码自学 **运动网2--抽象类中得到它在实现时的泛型类型
- hihocoder #1082 : 然而沼跃鱼早就看穿了一切
- JSONKit编译报错解决方法
- gcc/++编译so库
- 啊啊