数据结构与算法十:字符串匹配-暴力匹配算法与KMP算法

一、字符串匹配常用算法:

  • 暴力匹配
  • KMP算法

二、暴力匹配:

在这里插入图片描述

/**
 * @author:songwl
 * @Date:2022/2/15 22:03
 * @Description:
 */
public class Stringforcematch {


    public static void stringforcematch(String string1,String string2) {
        for(int i=0;i<string1.length();i++){
            for(int j=0;j<string2.length();j++){
                if(string1.charAt(i)==string2.charAt(j)){
                    i++;
                    if(j==string2.length()-1){
                        System.out.println("匹配成功:"+(i-j-1)+"到"+(i-1)+"位置");
                        return;
                    }
                }else{
                    i=i-j;
                    break;
                }
            }
        }
        System.out.println("匹配失败!");
    }

    public static void main(String[] args) {

        String string1 = "123songwen678songwenlong123";
        String string2 = "songwenlong";
        stringforcematch(string1,string2);

    }
}

二、KMP算法:

优势:暴力匹配具有大量的回朔,效率较低,时间复杂度为:O(mn);KPM算法利用先前比较的结果,减少回溯次数,提高了匹配效率,时间复杂度为:O(M+N)
原理:KMP为kmp三个发明人的名字首字母,只回溯j,不回溯i值,利用匹配字符串前缀与后缀,求出next[]数组,next数组的作用是匹配失败时确定j回溯的位置。

2.1 next数组的求法:

        String string1 = "abxabcabcaby";
        String string2 = "abcaby";

假如要从string1中找string2:

  • a.定义长度为string2.length()的数组int next[string2.length()]
  • b.设定next[0]=0
  • c.设定i=0;j=1;如果string2.charAt(i)==string2.charAt(j),则next[j]=i+1,i++,j++;否则如果
    i等于0时,next[j]=0,不等于0时i=next[i-1]位置,继续循环比较,直到j<nextArray.length
    private static int[] getNext(String string2) {
        int[] nextArray = new int[string2.length()];
        nextArray[0] = 0;
        for(int i=0,j=1;j<nextArray.length;j++){
            while(i>=0){
                if(string2.charAt(i)==string2.charAt(j)){
                    nextArray[j]=i+1;
                    i++;
                    break;
                }else if(i==0) {
                    nextArray[j]=0;
                    break;
                }else{
                     i=nextArray[i-1];
                    }
                }
            }
        System.out.println("\n结果为:");
        for(int temp:nextArray){
            System.out.print(temp+"\t");
        }
        return nextArray;
    }

2.2 利用next数组匹配:

        String string1 = "abxabcabcaby";
        String string2 = "abcaby";

假如要从string1中找string2:

  • a.设定i=0;j=0;i指向string1,j指向string2
  • b.;如果string1.charAt(i)==string2.charAt(j),则i++,j++,当j等于string2.length()则匹配成功;否则如果string1.charAt(i)!=string2.charAt(j) 则j=next[j-1],如果此时j等于0,则i++;
package example;

/**
 * @author:songwl
 * @Date:2022/2/16 11:59
 * @Description:
 */
public class KMPtest1 {

    public static void kMPtest1(String string1,String string2) {

        int[] nextArray = getNext(string2);

        for(int i=0,j=0;i<string1.length();){
            if(string1.charAt(i)==string2.charAt(j)){
                i++;
                j++;
                if(j==nextArray.length){
                    System.out.println("\nKMP匹配成功:"+(i-j)+"到"+(i)+"位置");
                    return;
                }
            }else{
                if(j==0){
                    i++;
                }else{
                    j=nextArray[j-1];
                }
            }
        }
        System.out.println("匹配失败!");

    }

    private static int[] getNext(String string2) {
        int[] nextArray = new int[string2.length()];
        nextArray[0] = 0;
        for(int i=0,j=1;j<nextArray.length;j++){
            while(i>=0){
                if(string2.charAt(i)==string2.charAt(j)){
                    nextArray[j]=i+1;
                    i++;
                    break;
                }else if(i==0) {
                    nextArray[j]=0;
                    break;
                }else{
                     i=nextArray[i-1];
                    }
                }
            }
        System.out.println("\n结果为:");
        for(int temp:nextArray){
            System.out.print(temp+"\t");
        }
        return nextArray;
    }

    public static void main(String[] args) {

        String string1 = "abxabcabcaby";
        String string2 = "abcaby";
//        String string1 = "123songwen678songwenlong123";
//        String string2 = "songwenlong";
        kMPtest1(string1,string2);
/*        String string1 = "abcdabca";
        String string2 = "aabaabaaa";
        getNext(string2);*/
    }
}

数据结构与算法更多相关内容【持续更新中】:

  • 【数据结构与算法一:时间频度和时间复杂度】: 传送门.
  • 【数据结构与算法二:数组】: 传送门.
  • 【数据结构与算法三:栈和队列】: 传送门.
  • 【数据结构与算法四:链表】: 传送门.
  • 【数据结构与算法五:哈希表-哈希函数设计原则-哈希冲突解决方案】: 传送门.
  • 【数据结构与算法八:分治算法(汉诺塔问题)】: 传送门.
  • 【数据结构与算法十:字符串匹配-暴力匹配算法与KMP算法】: 传送门.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值