牛客刷题日记2——腾讯2020(1压缩算法)--- Java

本文介绍了解决牛客网上一道关于字符串压缩算法的题目,详细解析了如何使用Java实现字符串的解压缩过程,包括使用栈来处理嵌套的压缩指令。

牛客刷题日记2——腾讯2020(1压缩算法)

题目:
小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为m|S,例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?
输入描述:
输入第一行包含一个字符串s,代表压缩后的字符串。
S的长度<=1000;
S仅包含大写字母、[、]、|;
解压后的字符串长度不超过100000;
压缩递归层数不超过10层;
输出描述:
输出一个字符串,代表解压后的字符串。
输入例子1:

HG[3|B[2|CA]]F

输出例子1:

HGBCACABCACABCACAF

例子说明1:

HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF

分析:
思路来源于大佬eisuto的博客:https://www.cnblogs.com/eisuto/p/12464469.html。思路大致为:遍历字符串,依次将字符存储在StringBuilder类型的res中(作为输出,同时也作为对输入字符串s的备份),记当前坐标为right。当遇到’[‘和’|‘时将对应入栈,遇到’]'时连续出栈两次,分别记为k和left。进过转化,重新定位right。此外代码考虑了不符合要求的输入,不加也能AC。
代码如下:

import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        String s = cin.next();

        //定义一个储存字符'['和'|'下标的栈
        Stack<Integer> st = new Stack<>();
        StringBuilder res = new StringBuilder();
        int right=0;
        for(char c:s.toCharArray()){
            res.append(c);
            if(c=='['||c=='|') st.push(right);
            if(c==']'){
                if(st.size()>=2){//此处判断下是否栈内存有'['和'|',防止输入有误导致异常
                    int k1 = st.pop();int left = st.pop();
                    String s1 = res.substring(k1+1,right);//获取'|'和']'之前的字符串
                    int num = Integer.parseInt(res.substring(left+1,k1));//获取'['后的数字
                    StringBuilder str = new StringBuilder();//涉及到字符串拼接,用StringBuilder效率高
                    for(int j=0;j<num;j++) str.append(s1);
                    res = res.replace(left,right+1,str.toString());
                    right = left + str.length()-1;//重新定位right的位置
                }else{
                    System.out.println("");
                    break;
                }
            }
            right++;
        }
        if(!st.isEmpty()) System.out.println("");//栈内不为空,则符号不匹配,不能返回正确结果
        System.out.println(res.toString());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值