Brute-Force 算法与KMP算法

串的模式匹配

串的模式匹配也叫查找定位,指的是在当前串中寻找模式串的过程。主要的模式匹配算法有 Brute-Force 算法 和 KMP 算法;

Brute-Force 算法

Brute-Force 算法从主串的第一个字符开始和模式串的第一个字符进行比较,若相等,则继续比较后续字符;否则从主串的第二个字符开始重新和模式串进行比较。依次类推,直到模式串的每个字符依次与主串的字符相等,匹配成功;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    //从位序号为begin的字符开始搜索与str相等的子串
	public int BF(String str, int begin) throws Exception {
		if(str.length()<=curLen&&str!=null&&curLen>0){
			int i=begin;
			int len=str.length();
			while(i<=curLen-len){//从主串的第i个元素开始比较
				for(int j=0;j<len;j++){//比较模式串的元素
				   if(str.charAt(j)!=strValue[j+i]){
					  i++;
					  break;  //跳出当前循环
				   }
				   else if(j==len-1){//len个字符全部匹配成功
					   return i;
				   }
			    }				
			}
		}
		return -1;
	}

Brute-Force 算法的实现简单,但效率非常低。
测试:

public class A {
	private char[] strValue;//字符数组存放串值
	private int curLen;//当前串的长度
	
	//构造空串
	public A(){
		strValue=new char[0];
		curLen=0;
	}
	//以字符串常量构造串
	public A(String str){
		char[] p=str.toCharArray();
		strValue=p;
		curLen=p.length;
	}
	
 	//从位序号为begin的字符开始搜索与str相等的子串
	public int BF(String str, int begin) throws Exception {
		if(str.length()<=curLen&&str!=null&&curLen>0){
			int i=begin;
			int len=str.length();
			while(i<=curLen-len){//从主串的第i个元素开始比较
				for(int j=0;j<len;j++){//比较模式串的元素
				   if(str.charAt(j)!=strValue[j+i]){
					  i++;
					  break;  //跳出当前循环
				   }
				   else if(j==len-1){//len个字符全部匹配成功
					   return i;
				   }
			    }				
			}
		}
		return -1;
	}
	      
    public static void main(String[] args) throws Exception{    	
        A aa =new A("ssdfgasdbababa");
        int result = aa.BF("fg", 0);
        System.out.println(result);    	 //输出3           
    }
}

KMP 算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

因此我们需要:

  1. 取得目标字符串的匹配值数组next[];
  2. 根据next[]数组实现KMP算法;

求数组next[]:

public static int[] kmpnext(String dest){
        int[] next = new int[dest.length()];
        next[0] = 0;
        for(int i = 1,j = 0; i < dest.length(); i++){
            while(j > 0 && dest.charAt(j) != dest.charAt(i)){
                j = next[j - 1];
            }
            if(dest.charAt(i) == dest.charAt(j)){            	
                j++;
            }
            next[i] = j;
        }
        return next;
    }

KMP实现:

    public static int kmp(String str, String dest,int[] next){//str文本串  dest 模式串
        for(int i = 0, j = 0; i < str.length(); i++){
            while(j > 0 && str.charAt(i) != dest.charAt(j)){
                j = next[j - 1];
            }
            if(str.charAt(i) == dest.charAt(j)){
                j++;
            }
            if(j == dest.length()){
                return i-j+1;
            }
        }
        return 0;
    }

测试:

    public static void main(String[] args){
    	//String a = "ababa";       输出9 0 0 1 2 3
       // String b = "ssdfgasdbababa";
    	String a = "dfg";        //输出2 0 0 0
        String b = "ssdfgasdbababa";    
        int[] next = kmpnext(a);
        int res = kmp(b, a,next);
        System.out.println(res);
        for(int i = 0; i < next.length; i++){
            System.out.println(next[i]);            
        }
        
    }

以上的内容来自51CTO学院的数据结构课程,我只是整理了一下以便日后方便复习,如有侵权我会自行删除;
原文:http://edu.51cto.com/center/course/lesson/index?id=68078
挺好理解的,讲师讲的很通熟易懂,想学习的可以去看原版视频;

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值