字符消消乐

字符消消乐

描述

有一个字符消除游戏,给定一个只包含大写字母‘ABC’的字符串s,消除过程是如下进行的:

  1. 如果s包含长度超过1的由相同字母组成的子串,那么这些子串会被同时消除,余下的子串拼成新的字符串。例如"ABCCBCCCAA"中“CCC“和"AA”会被同时消除,余下“AB”

  2. 上述消除会反复一轮一轮进行,直到新的字符串不包含相邻的相同字符为止。例如”ABCCBCCAA”经过一轮消除得到“ABB”,再经过一轮消除得到“A”

在消除开始前有机会在s中任意位置(第一个字符之前、最后一个字符之后以及相邻两个字符之间)插入输入的一个字符(‘A’,‘B’或者‘C’),得到字符串t。字符串除后,游戏最终得分是消除掉的字符的总数。

计算要如何插入字符,才能获得最高得分。

Input
输入第一行是插入的字符(‘A’ ‘B’或者‘C’)。
输入第二行是由’A"B"C组成的字符串s,长度不超过100。

Output

输出游戏的最高能得到的分数。

消除字符串部分代码

   /**
     * 进行字符串的消除
     * @param str 需要被消除的字符串
     * @return 消除完成的字符串
     */
    private static String replace(String str) {
        //跳出递归的条件
        int q = 0;
        //从第0位开始遍历
        //adsadddaaawqewssa
        for (int i = 0; i < str.length(); ) {//i==3
            //记录当前字符的位置 因为一旦消除 后面的字符就会移动这一位
            int m = i;//4
            //取当前下标的字符
            char c = str.charAt(i);//d
            int j = i + 1;//5
            for (; j < str.length(); j++) {
                if (c == str.charAt(j)) {
                    continue;
                }
                break;
            }
            //j=7
            if (j - i > 1) {
                q++;//代表当前字符串中还有需要消除的
                //adssaaaasqewssa
                str = str.substring(0, i) + str.substring(j);
                //因为被消除了 那么后面的字符串就会移动到之前的位置
                i = m;
                continue;
            }
            i++;
        }
        if (q == 0) {
            return str;
        }
        return replace(str);
    }

在执行字符串相邻并且相同的消除操作的时候,需要先判断后面一位是否是与前面一位相同的,如过相同,就需要一个值来进行记录,判断应该消除几个字符串,消除之后,后面的字符串就会移动到当前位置,所以我们需要一个值来记录被消除之前的下标。
第一次消除之后,后面的字符串会往前移动,相邻位置又可能有相同的字符串,所以我这里使用了递归进行下一次的判断消除。

进行插入操作部分代码

 /**
     * 进行插入操作
     * @param str 需要进行判断消除的字符串
     * @return 被插入的字符串的位置
     */
    private static int insert(String str) {
        //两个指针 差距最大的
        int max = 0;
        int index = 0;//记录插入的位置
        //4   cbabc
        for (int i = 1; i < str.length(); i++) {
            //k前移动 j后移动  ABABCBABABACBBCBAB
            for (int k = i - 1, j = i + 1; k >= 0 && j < str.length(); k--, j++) {
                if (str.charAt(k) == str.charAt(j)) {
                    if (k - 1 >= 0 && j + 1 < str.length()) {
                        continue;
                    }
                }
                if (j - k > max) {
                    max = j - k;
                    index = i;
                }
                break;
            }
            if (max > (str.length() - i) * 2) {
                break;
            }
        }

        return index;
    }

该方法使用的是双指针法,传入需要被插入一个字符,并且插入字符之后消除得最多的字符串,定义j、k两个指针,k向前移动,j向后移动,如果他们所在的位置的字符串相同就直接再次移动,直到不相等。

完整代码

/**
 * 字符消消乐
 * @author young先森00
 */
public class Test {
    public static void main(String[] args) {
        //ABABCBACBCBAB
        //ABABCBABABABCBCBAB
        //ABABCBABABACBBCBAB
        String begin = "CAABBCABAAACCABCBACCBABAABBABCBCBAB";
        String str = replace(begin);
        System.out.println("第一次消除的结果为" + str);
        //插入
        int i = insert(str);
        System.out.println("在第:" + i + "位插入:" + str.charAt(i));
        String s = str.substring(0, i) + str.charAt(i) + str.substring(i);
        System.out.println("插入后字符串变为:" + s);
        //插入后再次消除得到最终结果
        String end = replace(s);
        System.out.println("消除的最终结果为:" + end);
        System.out.println("插入后最后得分为:" + (begin.length() - end.length()));
    }

    /**
     * 进行插入操作
     * @param str 需要进行判断消除的字符串
     * @return 被插入的字符串的位置
     */
    private static int insert(String str) {
        //两个指针 差距最大的
        int max = 0;
        int index = 0;//记录插入的位置
        //4   cbabc
        for (int i = 1; i < str.length(); i++) {
            //k前移动 j后移动  ABABCBABABACBBCBAB
            for (int k = i - 1, j = i + 1; k >= 0 && j < str.length(); k--, j++) {
                if (str.charAt(k) == str.charAt(j)) {
                    if (k - 1 >= 0 && j + 1 < str.length()) {
                        continue;
                    }
                }
                if (j - k > max) {
                    max = j - k;
                    index = i;
                }
                break;
            }
            if (max > (str.length() - i) * 2) {
                break;
            }
        }

        return index;
    }

    /**
     * 进行字符串的消除
     * @param str 需要被消除的字符串
     * @return 消除完成的字符串
     */
    private static String replace(String str) {
        //跳出递归的条件
        int q = 0;
        //从第0位开始遍历
        //adsadddaaawqewssa
        for (int i = 0; i < str.length(); ) {//i==3
            //记录当前字符的位置 因为一旦消除 后面的字符就会移动这一位
            int m = i;//4
            //取当前下标的字符
            char c = str.charAt(i);//d
            int j = i + 1;//5
            for (; j < str.length(); j++) {
                if (c == str.charAt(j)) {
                    continue;
                }
                break;
            }
            //j=7
            if (j - i > 1) {
                q++;//代表当前字符串中还有需要消除的吧 1
                //adssaaaasqewssa
                str = str.substring(0, i) + str.substring(j);
                //因为被消除了 那么后面的字符串就会移动到之前的位置
                i = m;
                continue;
            }
            i++;
        }
        if (q == 0) {
            return str;
        }
        return replace(str);
    }
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值