KMP算法Java实现

构造部分匹配表

部分匹配表的构建思路
在这里插入图片描述

	// 获取部分匹配表
    public static List<Integer> getPartialMatchingTable(String subString){
        if(StringUtils.isEmpty(subString)){
            return new ArrayList<>();
        }
        List<String> tempList = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Integer> keyPairs = new ArrayList<>();
        // 拆字符串 ABCDABD
        // A AB ABC ABCD ABCDAB ABCDABD
        for(int i=0;i<subString.length();i++){
            sb.append(subString.charAt(i)+"");
            tempList.add(sb.toString());
        }

        for(String str:tempList){
            if(str.length()==1){
                keyPairs.add(0);
                continue;
            }
            StringBuilder leftSb = new StringBuilder();
            StringBuilder rightSb = new StringBuilder();
            int count = 0;
            for(int i=0;i<str.length()-1;i++){
                leftSb.append(str.charAt(i)+"");
                rightSb.insert(0,str.charAt(str.length()-1-i)+"");
                if(leftSb.toString().equals(rightSb.toString())){
                    count = leftSb.length();
                }
            }
            keyPairs.add(count);
        }
        return keyPairs;
    }	

给定主串和子串,获取到满足条件的索引位置

	public static int getfirstIndex(String source,String subString,Map<Integer, Integer> partialMatchingTableMap){
        int index = -1;
        if(source.isEmpty()||subString.isEmpty()||source.length()<subString.length()){
            return index;
        }
        int subStringIndex = -1;
        int firstMatchIndex = -1;
        boolean firstMathch = true;
        for(int i=0;i<source.length();i++){
            if((source.charAt(i)+"").equals((subString.charAt(subStringIndex+1)+""))){
                if(firstMathch){
                    firstMatchIndex = i;
                    firstMathch = false;
                }
                // 找到了,更新匹配的在substirng中的位置
                subStringIndex++;
                // 完成匹配
                if(subStringIndex == subString.length()-1){
                    return firstMatchIndex;
                }

            }else if(!firstMathch){  // 匹配过的走这里
                // 移动位数 = 已匹配的字符数 - 对应的部分匹配值
                // 不匹配,查看需要往回倒的长度
                int step = (subStringIndex+1) - partialMatchingTableMap.get(subStringIndex);

                // 新位置开始,相关参数置空
                i = firstMatchIndex+step;
                subStringIndex = -1;
                firstMathch = true;
                firstMatchIndex = -1;

                // i重置,此次索引不要动
                i--;
            }
        }
        return index;
    }

测试结果

	public static void main(String[] args) {
        String source = "BBC ABCDAB ABCDABCDABDE";
        String subString = "ABCDABD";
        // 获取部分匹配表
        List<Integer> partialMatchingTable = getPartialMatchingTable(subString);
        Map<Integer, Integer> partialMatchingTableMap = new HashMap<>();
        for(int i=0;i<partialMatchingTable.size();i++){
            partialMatchingTableMap.put(i,partialMatchingTable.get(i));
            System.out.print(i+" ");
        }
        System.out.println();
        for(int i=0;i<partialMatchingTable.size();i++){
            System.out.print(partialMatchingTable.get(i)+" ");
        }

        // 查找初次匹配的主串位置
        int i = getfirstIndex(source, subString, partialMatchingTableMap);
        System.out.println();
        System.out.println("主串:"+source);
        System.out.println("子串:"+subString);
        System.out.println(subString+"在"+source+"中"+"匹配到的位置在主串中是: "+i);

    }

执行效果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值