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()+"} 个匹配结果");

    }
}
时间: 2024-10-14 10:02:10

java实现的kmp算法的相关文章

hdu 2594 java实现字符串KMP算法

Problem Description Homer: Marge, I just figured out a way to discover some of the talents we weren't aware we had. Marge: Yeah, what is it? Homer: Take me for example. I want to find out if I have a talent in politics, OK? Marge: OK. Homer: So I tak

【数据结构&amp;&amp;算法系列】KMP算法介绍及实现(c++ &amp;&amp; java)

KMP算法如果理解原理的话,其实很简单. KMP算法简介 这里根据自己的理解简单介绍下. KMP算法的名称由三位发明者(Knuth.Morris.Pratt)的首字母组成,又称字符串查找算法. 个人觉得可以理解为最小回溯算法,即匹配失效的时候,尽量少回溯,从而缩短时间复杂度. KMP算法有两个关键的地方,1)求解next数组,2)利用next数组进行最小回溯. 1)求解next数组 next数组的取值只与模式串有关,next数组用于失配时回溯使用. 在简单版本的KMP算法中,每个位置 j 的 n

经典KMP算法C++与Java实现代码

前言: KMP算法是一种字符串匹配算法,由Knuth,Morris和Pratt同时发现(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.比较流行的做法是实现一个next()函数,函数本身包含了模式串的局部匹配信息.由于next函数理解起来不太容易,本文同样是基于空间换时间的做法,但将采用另一种代码实现,希望可以更方便读者理解! 测试数据 aseeesatba esat as330kdwejjl_8 jjl_ faw4etoesting

KMP 算法 java实现

KMP算法讲解 我的Java代码实现 package jj4_6; public class KMP { public static boolean contains(String a,String b){ /* * 第一步,对b字符串做一个预处理 */ Integer[] fuzhu = new Integer[b.length()]; for(Integer i= 0;i<b.length();i++){ // i == 3 时 // nowstr = "abab" Stri

KMP算法-Java实现

目的: 为了解决字符串模式匹配 历程: 朴素模式匹配:逐次进行比较 KMP算法:利用匹配失败得到的信息,来最大限度的移动模式串,以此来减少比较次数提高性能 概念: m:是目标串长度 n:是模式串长度 j:某次匹配时,第一次出现的不同的索引位置(有的称为:失配位) k:最长首尾串长度(有的称为:最长公共前后缀) 核心思想: S   S0 S1 ...... Si-j-1 Si-j Si-j+1 Si-j+2 ...... Si-2 Si-1 Si ...... Sn-1 ||     ||    

Java实现KMP算法

转自:http://blog.csdn.net/tkd03072010/article/details/6824326 —————————————————————————————————— package arithmetic; /** * Java实现KMP算法 * * 思想:每当一趟匹配过程中出现字符比较不等,不需要回溯i指针, * 而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远 * 的一段距离后,继续进行比较. * * 时间复杂度O(n+m) * * @author xqh

KMP算法java实现

/** * 假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置 如果j = -1,或者当前字符匹配成功(即S[i] == * P[j]),都令i++,j++,继续匹配下一个字符: 如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = * next[j],此举意味着模式串P相对于文本串S向右移动了至少1位(换言之,当匹配失败时,模式串向右移动的位数为:失配字符所在位置 - * 失配字符对应的next 值,即移动的实际位数为:j - next[j],且

KMP算法详解及其Java实现

KMP算法,又称作"看猫片"算法(误),是一种改进的字符串模式匹配算法,可以在O(n+m)的时间复杂度以内完成字符串的匹配操作,其核心思想在于:当一趟匹配过程中出现字符不匹配时,不需要回溯主串的指针,而是利用已经得到的"部分匹配",将模式串尽可能多地向右"滑动"一段距离,然后继续比较. KMP(看猫片)算法 1. 朴素的字符串模式匹配算法 求一个字符串(模式串)在另一个字符串(主串)中的位置,称为字符串模式匹配. 在朴素的字符串模式匹配算法中,我

Java数据结构之字符串模式匹配算法---KMP算法

本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯指针,而是利用已经得到的"部分匹配"结果将模式向右"滑动"尽可能远的一段距离,继续进行比较.显然我们首先需要获取一个"部分匹配"的结果,该结果怎么计算呢? 二.算法分析 在上一篇中讲到了BF算法,