zoukankan      html  css  js  c++  java
  • 猿辅导:字符压缩算法(括号匹配)

    题目描述

      猿辅导APP需要下发一些宣传文本给学生,工程师们使用了一种字符压缩算法,为了简单起见,假设被压缩的字符全部为大写字母序列,A,B,C,D,E……Z,压缩规则如下:

      1. AAAB 可以压缩为 A3B(单字符压缩不加括号)

      2. ABABA 可以压缩为 (AB)2A (多字符串压缩才加括号)

      输入数据保证不会出现冗余括号,且表示重复的数字一定合法且大于1,即不会出现:

      1. (A)2B ---------(应为:A2B)
      2. ((AB))2C ---------(应为:(AB)2C)
      3. (A)B ---------(应为:AB)
      4. A1B ---------(应为:AB)

       注意:数字可能出现多位数即 A11B 或者 (AB)10C 或者 A02这种情况

      A11B = AAAAAAAAAAAB

       (AB)10C = ABABABABABABABABABABC

      A02 = AA

    数据分布:

        对于60%的数据,括号不会出现嵌套,即不会有((AB)2C)2 这种结构。

        对于80%的数据,括号最多嵌套1层-,不会有(((AB)2C)2D)99这种结构。

        对于100%的数据,括号可以嵌套任意层

    输入描述:

      第一行是正整数C(C<=100),表示下面有C组数据。

      之后C行,每一行为一组数据,每组数据为一个字符串。

      每个字符串由A-Z,0-9,(,),组成表示一个压缩后的串,保证输入数据一定合法且字符串长度小于50

    5
    A11B
    (AA)2A
    ((A2B)2)2G
    (YUANFUDAO)2JIAYOU
    A2BC4D2

    输出描述:

      输出C行,每行读音一个数据的输出结果,表示压缩前的字符串,保证每个字符串展开的长度不超过10^6.

    AAAAAAAAAAAB
    AAAAA
    AABAABAABAABG
    YUANFUDAOYUANFUDAOJIAYOU
    AABCCCCDD

    分析

      括号匹配,用栈来实现

    代码 

    import java.util.Scanner;
    import java.util.Stack;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int C=sc.nextInt();//字符串数目
            sc.nextLine();
            String[] str = new String[C];//保存字符串
            for (int i = 0; i < C; i++) {
                str[i] = sc.nextLine();
            }
            for (int i = 0; i < C; i++) {
                String results = decompressChar(str[i]);
                System.out.println(results);
            }
        }
        /**
         * 将字符串解压缩
         * @param str
         * @return
         */
        public static String decompressChar(String str) {
            StringBuilder sb = new StringBuilder("");
            StringBuilder tmp = new StringBuilder("");
            char flag = '(';
            Stack<Character> stack = new Stack<Character>();
            char[] chars = str.toCharArray();//将压缩后的字符串转为字符数组
            int count = 0;//用于保存字符串重复的次数
            //遍历每个数组将其放入栈中
            for (int i = 0; i < chars.length; i++) {
                /**获取字符串需要重复的次数*/
                while(i < chars.length && (chars[i] + "").matches("[0-9]")){
                    count = count * 10 + Integer.parseInt(chars[i] + "");
                    i++;
                }
                /**解压字符串并放入栈中*/
                count = putUnCompressedValueToStack(count, tmp, stack);
                if(i == chars.length){break;}//如果数字字符位于字符串末尾,直接跳出
                /**如果是 ( 直接放入栈中*/
                if (chars[i] =='(') {
                    stack.push(chars[i]);
                /**如果是 ) 从栈中获取需要重复的字符子串,并将)移除栈*/
                }else if (chars[i] ==')') {
                    tmp = getStackValue(stack, flag);
                    stack.pop();
                /**如果是字母*/
                }else if((chars[i] + "").matches("[A-Z]")) {
                    // 如果是单个字母重复,获取单个字母
                    if(i < (chars.length-1) && (chars[i+1] + "").matches("[0-9]")){
                        tmp = new StringBuilder("").append(chars[i]);
                    // 字母不重复,直接入栈
                    }else{
                        stack.push(chars[i]);
                    }
                }
            }
            /**获取栈中所有的字符串*/
            sb = getStackValue(stack, flag);
            /**注意栈先进先出,需要逆转字符串*/
            return sb.reverse().toString();
        }
        
        /**
         * 获得栈中的元素,直到值与character相等
         * @param stack 栈
         * @param character 某个字符
         * @return
         */
        public static StringBuilder getStackValue(Stack<Character> stack, Character character){
            StringBuilder tmp = new StringBuilder("");
            while(!stack.isEmpty() && stack.peek()!= character){
                tmp.append(stack.peek());
                stack.pop();
            }
            return tmp;
        }
        
        /**
         * 解压字符串并放入栈中
         * @param count tmp重复的次数
         * @param tmp    需要重复的字符串
         * @param stack    栈
         * @return
         */
        public static int putUnCompressedValueToStack(int count,StringBuilder tmp, Stack<Character> stack){
            if(count>0 && tmp.length()!=0){
                for (int j = 0; j < count; j++) {
                    for (int k = tmp.length()-1; k>=0; k--) {
                        stack.push(tmp.charAt(k));
                    }
                }
            }
            return 0;
        }
    }
  • 相关阅读:
    python-面向对象-类
    python- collections-time-datetime
    python-json-pickle-shelve-random-os-sys-hashlib
    python-递归函数
    python-迭代器
    python-内置函数
    python-易错问题
    python-闭包函数和装饰器
    pytho-函数作用域
    List 拆分集合与 读写XML配置文件
  • 原文地址:https://www.cnblogs.com/haimishasha/p/11300767.html
Copyright © 2011-2022 走看看