算法 - KMP算法

package com.mzs.testThread1;

public class TestDemo {
    /**
     * KMP核心:获取next数组,(本方法为其中的一种)
     * 数组的每个元素是从0位到该元素下标位的最大前缀后缀的字符串长度
     * @param str 模式字符串
     * @return next数组
     */
	private static int[] getNextArray(String str) {
        char[] array = str.toCharArray();   // 定义模式字符串数组
        int[] nextArray = new int[str.length()];    // 定义next数组
        nextArray[0] = 0;   // 设置next数组第一个元素为0(数学逻辑:必须为0)
        int tOrder = 1;    // 从下标为1开始计算数组元素值
        int maxPreSuf = 0;  // 前缀后缀字符串相同时的最大长度,(其实就是模式字符串匹配的长度)
        while (tOrder < str.length()) {
            while (maxPreSuf > 0 && array[maxPreSuf] != array[tOrder])  // (maxPreSuf没在起始位置,且失配时)
            	maxPreSuf = nextArray[maxPreSuf - 1];	// (算法核心):回溯到索引为上一个最大前缀后缀长度的next数组元素值处
            if (array[maxPreSuf] == array[tOrder]) // 匹配时
                maxPreSuf++; 
            nextArray[tOrder] = maxPreSuf;	// 模式字符串数组从0到tOrder,这个字符串的匹配的长度也就是next数组的元素值
            tOrder++;
        }
        return nextArray;
    }
 
    /**
     * KMP算法
     * @param str 主字符串
     * @param str1 模式字符串
     */
    private static void getKMP(String str, String str1) {
        char[] array = str.toCharArray();   // 主字符数组
        char[] array1 = str1.toCharArray(); // 模式字符数组
        int[] nextArray = getNextArray(str1);    // 获取模式字符串的next数组
        int sOrder = 0; // 模式字符数组起始下标,(也就是模式字符串匹配的长度)
        for (int i = 0; i < str.length(); i++) {
            while (sOrder > 0 && array[i] != array1[sOrder]) // 下标没在初始位置,且失配时
            	sOrder = nextArray[sOrder - 1];	// 回溯到索引为上一个sOrder的next数组的位置处
            if (array[i] == array1[sOrder]) // 匹配时
                sOrder++;
            if (str1.length() == sOrder) { // 完全匹配时
                System.out.println("succeed to find at " + (i - sOrder + 1)); // 输出模式字符串的第一个字符在主字符串的位置
                return ;
            }
        }
        System.out.println("no matching, fail to find"); // 输出没有匹配到
    }
 
    public static void main(String[] args) {
        String str = "abcdababaabababcacbaccfabfcdabcdf";
        String str1 = "abababca";
        getKMP(str, str1);
        int[] array = getNextArray(str1);
        for (int i = 0; i < array.length; i++) {
        	System.out.print(array[i] + " ");
        }
    }

	
	
}

猜你喜欢

转载自blog.csdn.net/qq_34561892/article/details/83869762