KMP算法与JDK中的BF 测试

KMP实现

package com.algorithm.search;

import java.util.Random;

public final class KMP {
    private final char[] value;
    private final int count;
    
    public KMP(String str){
        value = str.toCharArray();
        count = value.length;
    }
    
    /**
     * 计算模式串匹配失败时,需要移动到的位置
     * @param pattern
     * @return
     */
    private int[] buildNext(char[] source){
        int[] next = new int[source.length];
        
        next[0] = 0;
        for(int i = 1; i < source.length; i++){
            int k = 0;
            int start = 0;
            int end = i - 1;
            while(end > 0 && source[start++] == source[end--])
                k++;
            next[i] = k;
        }
        
        return next;
    }
    
    public int indexOf(String pattern){
        char[] target = pattern.toCharArray();
        int[] next = buildNext(target);
        
        int end = target.length -1;
        int sourceMax = count - target.length;    //主串最大移动到该位置,剩下不够模式串的长度
        int sourceOffset = 0;
        int targetOffset = 0;
        while(sourceOffset <= sourceMax){
            while(sourceOffset <= sourceMax && target[targetOffset] != value[sourceOffset]){
                sourceOffset++;
            }
            while (target[++targetOffset] == value[++sourceOffset]) {
                if(targetOffset == end){
                    return sourceOffset - end;
                }
            }
            targetOffset = next[targetOffset];
        }
        
        return -1;
    }
    
    public static void main(String[] args){
        for (int i = 0; i < 3; i++){
            String sourceString = getString(10000000);
            String pattern = getString(200);
            
            KMP kmp = new KMP(sourceString);
            long start = System.currentTimeMillis();
            int index = kmp.indexOf(pattern);
            System.out.println("KMP find:" + index);
            System.out.println("KMP耗时:" + (System.currentTimeMillis() - start) + "ms");
            
            long start2 = System.currentTimeMillis();
            int index2 = sourceString.indexOf(pattern);        
            System.out.println("JDK find:" + index);
            System.out.println("JDK BF耗时:" + (System.currentTimeMillis() - start2) + "ms");
            
            System.out.println("************************");
        }
    }
    
    private static String getString(int max){
        String table = "-abcdefghijklmnopqrstuvwxyz";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < max; i++){            
            int index = random.nextInt(27);
            sb.append(table.charAt(index));
            //sb.append("ababcabcacbab");
        }
        
        return sb.toString();
    }
}

测试结果

KMP find:-1
KMP耗时:78ms
JDK find:-1
JDK BF耗时:32ms
************************
KMP find:-1
KMP耗时:78ms
JDK find:-1
JDK BF耗时:31ms
************************
KMP find:-1
KMP耗时:62ms
JDK find:-1
JDK BF耗时:47ms
************************

实际情况并不是所想的KMP算法就一定快,模式串小的话,BF回朔的距离并不远,模式串长的话,KMP在建立next数组相应也要花更长的时间

KMP针对特定的字符串格式才能体现效率

转载于:https://www.cnblogs.com/xuruhong/p/3287462.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值