猿辅导:字符压缩算法(括号匹配)

题目描述

  猿辅导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;
    }
}

原文地址:https://www.cnblogs.com/haimishasha/p/11300767.html

时间: 2024-10-08 23:48:00

猿辅导:字符压缩算法(括号匹配)的相关文章

括号匹配问题 -算法专题

算法数据结构面试分享 符号匹配问题 今天在帖子上看见有同学在问,如果一个字符串中包含大括号和小括号,我们该如何解决括号匹配问题.我们今天就一起看下这道题吧.按照我们之前的套路,按部就班来: 确保我们理解了问题,并且尝试一个例子,确认理解无误. 举个例子,这样的括号是匹配的, ().{}.({}), ({()}(){}), 而类似于{(.{,({)都是不匹配的. 想想你可以用什么方法解决问题,你会选择哪一种,为什么? 我们拿这个字符串为例,({()}(){}), 最后一个)匹配的是第一个(, 倒数

括号匹配问题(顺序栈实现)

本周老师作业留了两个.先上传一个吧.那个有时间我再传上来~ 本周的要求: 1.给出顺序栈的存储结构定义. 2.完成顺序栈的基本操作函数. 1)      初始化顺序栈 2)      实现入栈和出栈操作 3)      实现取栈顶元素和判空操作 括号匹配问题 3.编写主函数实现基本操作函数功能,并设置测试数据,测试合法和非法数据的输出结果. 4.程序调试运行并保存输出结果. 5.整理并提交实验作业. 1 #include <cstdio> 2 #include <cstring>

括号匹配(二)

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不

动态规划(2)--括号匹配(二)

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超

栈的应用-判断括号匹配

栈的一个典型应用就是可以用来协助分析表达式的括号是否匹配.括号可以延伸到任何成对出现的界定符,例如引号,书名号等. 接下来给出程序实现: 第一部分给出的是堆栈的插入,删除等操作对应的实现: 1 public class StackChar 2 { 3 private int maxSize;//堆栈数组大小 4 private char [] stackArray; 5 private int top;//堆栈顶 6 public StackChar(int maxSize) 7 { 8 thi

数据结构上机3栈-括号匹配

#include <stdio.h> #include <malloc.h> #define OK 1 #define OVERFLOW -1 #define ERROR 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef char SElemType; typedef int Status; typedef struct{ SElemType * base; SElemType * top; int st

栈的两个应用:括号匹配的检验和表达式求值

1.     括号匹配的检验 假设表达式中含有3种括号:(),[],{},其嵌套的顺序随意.检验括号是否匹配. 基本思想:在算法中设置一个栈,每读入一个括号,若是右括号,则或者与栈顶匹配的左括号相互消解,或者是不合法的情况:若是左括号,则直接压入栈中.若括号匹配,在算法的开始和结束时,栈都应该是空的. 代码: /* * 判断表达式中的括号是否匹配,匹配输出Yes,否则输出No * {(zhang)+[lei]+{lei}={zhangleilei}} -> Yes * {(zhang)+[lei

华为上机练习题--括号匹配检测

题目: 输入一串字符串,其中有普通的字符与括号组成(包括'('.')'.'[',']'),要求验证括号是否匹配,如果匹配则输出0.否则输出1. Smple input:dfa(sdf)df[dfds(dfd)]    Smple outPut:0 分析: 类似于括号字符匹配这类的问题, 我们可以模拟栈的操作来进行验证, 这样问题就简单了, 就是栈的操作 代码如下: package com.wenj.test; import java.util.ArrayList; import java.uti

括号匹配为题(栈的思想)哈

数据结构实验之栈四:括号匹配 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给你一串字符,不超过50个字符,可能包括括号.数字.字母.标点符号.空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入 输入数据有多组,处理到文件结束. 输出 如果匹配就输出“yes”,不匹配输出“no” 示例输入 sin(20+10) {[}] 示例输出 yes no 提示 我的分析:运用栈的思想,读到左边的括号,就把它推进