字符串解码(Java)

给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: n[encodedString],表示其中方括号内部的 encodedString 正好重复 n 次。注意 n 保证为正整数。
可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,可以认为原始数据不包含数字,所有的数字只表示重复的次数 n ,例如不会出现像 3a 或 2[4] 的输入。


示例 1:
输入:str = "3[a]2[bc]"
输出:"aaabcbc"

示例 2:
输入:str = "3[a2[c]]"
输出:"accaccacc"

示例 3:
输入:str = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

示例 4:
输入:str = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

package com.loo;

import java.util.Collections;
import java.util.LinkedList;

public class DecodeString {
    
    public static int ptr = 0;
    public static String src = null;

    public static void main(String[] args) {
        String s1 = "3[a]2[bc]";
        String s2 = "3[a2[c]]";
        String s3 = "2[abc]3[cd]ef";
        String s4 = "abc3[cd]xyz";
        System.out.println(decodeString(s1));
        System.out.println(decodeString(s2));
        System.out.println(decodeString(s3));
        System.out.println(decodeString(s4));
        System.out.println(decodeString2(s1));
        System.out.println(decodeString2(s2));
        System.out.println(decodeString2(s3));
        System.out.println(decodeString2(s4));
    }
    
    // 栈操作
    // 如果当前的字符为数位,解析出一个数字(连续的多个数位)并进栈
    // 如果当前的字符为字母或者左括号,直接进栈
    // 如果当前的字符为右括号,开始出栈,一直到左括号出栈,出栈序列反转后拼接成一个字符串,
    // 此时取出栈顶的数字,就是这个字符串应该出现的次数,我们根据这个次数和字符串构造出新的字符串并进栈
    // 重复如上操作,最终将栈中的元素按照从栈底到栈顶的顺序拼接起来,就得到了题目要求的解
    public static String decodeString(String str) {
        LinkedList<String> lk = new LinkedList<String>();
        ptr = 0;
        while (ptr < str.length()) {
            char curr = str.charAt(ptr);
            if (Character.isDigit(curr)) {
                String digit = getDigits(str);
                lk.addLast(digit);
            } else if (Character.isLetter(curr) || curr == '[') {
                lk.addLast(String.valueOf(str.charAt(ptr++)));
            } else {
                ++ptr;
                LinkedList<String> sub = new LinkedList<String>();
                while (!"[".equals(lk.peekLast())) {
                    sub.addLast(lk.removeLast());
                }
                Collections.reverse(sub);
                lk.removeLast();
                int times = Integer.parseInt(lk.removeLast());
                StringBuffer buff = new StringBuffer();
                String result = getString(sub);
                while (times-->0) {
                    buff.append(result);
                }
                lk.addLast(buff.toString());
            }
        }
        return getString(lk);
    }
    
    public static String getDigits(String s) {
        StringBuffer sb = new StringBuffer();
        while (Character.isDigit(s.charAt(ptr))) {
            sb.append(s.charAt(ptr++));
        }
        return sb.toString();
    }
    
    public static String getString(LinkedList<String> lk) {
        StringBuffer sb = new StringBuffer();
        for (String s : lk) {
            sb.append(s);
        }
        return sb.toString();
    }
    
    // 递归
    public static String decodeString2(String str) {
        src = str;
        ptr = 0;
        return getString2();
    }
    
    public static String getString2() {
        if (ptr == src.length() || src.charAt(ptr) == ']') {
            return "";
        }
        char curr = src.charAt(ptr);
        int times = 1;
        String result = "";
        if (Character.isDigit(curr)) {
            times = getDigits2();
            ptr++;
            String str = getString2();
            ptr++;
            while (times-->0) {
                result += str;
            }
        } else if (Character.isLetter(curr)) {
            result = String.valueOf(src.charAt(ptr++));
        }
        return result + getString2();
    }
    
    public static int getDigits2() {
        int ret = 0;
        while (ptr<src.length() && Character.isDigit(src.charAt(ptr))) {
            ret = ret * 10 + src.charAt(ptr++) - '0';
        }
        return ret;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值