南阳ACM 第5题 BinaryMatch KMP算法实现

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;


public class KMPequal {

    List<Integer> MaxList = new ArrayList<Integer>();

    public static int[] getMaxEqual(char[] str) {
        int length = str.length;
        int[] maxIndex = new int[length];
        for (int i = 0; i < length; i++)
            maxIndex[i] = 0;

        for (int i = 1; i < length; i++) {
            for (int j = 0; j < i; j++) {
                for (int k = 0; k <= j; k++) {
                    if (str[i - j + k] != str[k]) {
                        break;
                    } else if (k == j) {
                        maxIndex[i] = j + 1 > maxIndex[i] ? j + 1 : maxIndex[i];

                    }
                }

            }
        }
        return maxIndex;

        // int q, k;// q:模版字符串下标;k:最大前后缀长度
        // int m = str.length;// 模版字符串长度
        // int[] next = new int[m];
        // next[0] = 0;// 模版字符串的第一个字符的最大前后缀长度为0
        // for (q = 1, k = 0; q < m; ++q)// for循环,从第二个字符开始,依次计算每一个字符对应的next值
        // {
        // while (k > 0 && str[q] != str[k])
        // // 递归的求出P[0]···P[q]的最大的相同的前后缀长度k
        // k = next[k - 1]; // 不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解
        // if (str[q] == str[k])// 如果相等,那么最大相同前后缀长度加1
        // {
        // k++;
        // }
        // next[q] = k;
        // }
        // return next;
    }

    public static int countEqual(String models, String objects) {
        int count = 0;
        char[] object = objects.toCharArray();
        char[] model = models.toCharArray();
        int[] next = getMaxEqual(model);
        int o_length = object.length;
        int n_length = next.length;
        int i = 0;
        while (i < o_length) {
            for (int j = 0; j < n_length;) {
                if (i + j >= o_length) {
                    i += j;
                    break;
                } else if (model[j] != object[j + i]) {
                    // System.out.println("匹配失败!"+i+"_____"+j);
                    i += j > 0 ? next[j - 1] + 1 : 1;
                    j = j > 0 ? next[j - 1] : 0;
                    continue;
                } else if (j == n_length - 1) {
                    // System.out.println("匹配成功!"+i+"_____"+j);
                    count++;
                    i += next[j];
                    j = next[j];
                } else {
                    j++;
                }

            }
        }

        return count;

    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int grounps = Integer.parseInt(cin.nextLine());
        int i = 0;
        int[] count = new int[grounps];

        while (i < grounps) {
            count[i++] = countEqual(cin.nextLine(), cin.nextLine());
        }

        for (int j : count)
            System.out.println(j);

        // System.out.println(countEqual("101", "110010010010001"));
    }

}

执行结果:

3
11
1001110110
101
110010010010001
1010
110100010101011
3
0
3 
点赞