面试金典——模式匹配

Q:你有两个字符串,即pattern和value。 pattern字符串由字母"a"和"b"组成,用于描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a","go"是"b"),该字符串也匹配像"a"、"ab"和"b"这样的模式。但需注意"a"和"b"不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。

示例 1:
输入: pattern = "abba", value = "dogcatcatdog"
输出: true

示例 2:
输入: pattern = "abba", value = "dogcatcatfish"
输出: false

示例 3:
输入: pattern = "aaaa", value = "dogcatcatdog"
输出: false

示例 4:
输入: pattern = "abba", value = "dogdogdogdog"
输出: true
解释: "a"="dogdog",b="",反之也符合规则
提示:

0 <= len(pattern) <= 1000
0 <= len(value) <= 1000
你可以假设pattern只包含字母"a"和"b",value仅包含小写字母。

A:
这个题不难,就是……参数太多,最好写的时候把参数写上注释,否则真的很容易用错参数。

public boolean patternMatching(String pattern, String value) {
        //pattern为空
        if (pattern.isEmpty())
            //判断value是否为空
            return value.isEmpty();
        if (!value.isEmpty() && pattern.length() > value.length())
            return false;
        int len = pattern.length();
        int len_v = value.length();
        int[] count = new int[2];
        Arrays.fill(count, 0);
        for (int i = 0; i < pattern.length(); i++) {
            if (pattern.charAt(i) == 'a')
                count[0]++;//a的数量
            else
                count[1]++;//b的数量
        }
        //只有一个pattern
        if (count[0] == 0 || count[1] == 0) {
            if (value.isEmpty())
                return true;
            int num = len_v / len;//字符串长度为num
            if (len_v % len != 0)
                return false;
            String str = value.substring(0, num);
            for (int i = 1; i < len; i++) {
                String sub = value.substring(i * num, (i + 1) * num);
                if (!sub.equals(str))
                    return false;
            }
            return true;
        }
        //如果pattern里ab都有但value为空,返回false
        if (value.isEmpty())
            return false;
        //pattern里面有a有b
        int factor1;//数量多的值的数量
        int factor2;//数量少的值的数量
        int c1;//数量多的值
        int c2;//数量少的值
        if (count[0] >= count[1]) {
            factor1 = count[0];
            c1 = 'a';
            factor2 = count[1];
            c2 = 'b';
        } else {
            factor1 = count[1];
            c1 = 'b';
            factor2 = count[0];
            c2 = 'a';
        }
        int num = len_v / factor1;//数量多的值对应字符串最大的长度
        for (int i = 0; i <= num; i++) {//i是数量多的值对应的字符串的长度
            if ((len_v - i * factor1) % factor2 != 0) {
                continue;
            }
            boolean flag = false;
            int j = (len_v - i * factor1) / factor2;//j是数量少的值对应的字符串的长度
            int index = 0;
            String str1 = null;//数量多的值对应的字符串
            String str2 = null;//数量少的值对应的字符串
            for (int k = 0; k < pattern.length(); k++) {
                if (pattern.charAt(k) == c1) {
                    String sub = value.substring(index, index + i);
                    index = index + i;
                    if (str1 == null) {
                        str1 = sub;//第一次遇到数量多的值对应的字符串
                    } else {
                        if (!str1.equals(sub)) {
                            flag = true;
                            break;
                        }
                    }
                } else if (pattern.charAt(k) == c2) {
                    String sub = value.substring(index, index + j);
                    index = index + j;
                    if (str2 == null) {
                        str2 = sub;//第一次遇到数量少的值对应的字符串
                    } else {
                        if (!str2.equals(sub)) {
                            flag = true;
                            break;
                        }
                    }
                } else
                    //碰到ab以外的值
                    return false;
            }
            //当前字符长度取的不对
            if (flag)
                continue;
            //当前字符长度取的对
            else
                return true;
        }
        return false;
    }
原文地址:https://www.cnblogs.com/xym4869/p/12674622.html