Java实现字符串解码

题目描述

题目来源于leetcode:https://leetcode-cn.com/explore/learn/card/queue-stack/220/conclusion/890/

字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

示例 1:

输入:s = “3[a]2[bc]”
输出:“aaabcbc”
示例 2:

输入:s = “3[a2[c]]”
输出:“accaccacc”
示例 3:

输入:s = “2[abc]3[cd]ef”
输出:“abcabccdcdcdef”
示例 4:

输入:s = “abc3[cd]xyz”
输出:“abccdcdcdxyz”

分析

此题类似逆波兰表达式,但是更复杂。

我们定义StringBuffer类val来储存最终的结果,val的值是实时变换的;定义2个栈,一个字母栈,一个数字栈分别存储字母与数字;

何时入栈和出栈呢?我认为这就是此题的难点,很明显不可能当为数字的时候,或者为字母的时候就入栈。应该是当为 ’ [ ’ 入栈,当为 ’ ] ’ 出栈,因为题目输入字符串总是有效的,在出现 ’ [ ’ 前,字母不进行任何变换,一旦出现
’ [ ',我们通过入栈来“保留现场”;而出现 ’ ] ’ ,字符串进行变换,并且通过出栈来“回到现场”。

把val作为即将入栈的字符串,定义入栈的数字number;
遍历输入的字符串中的元素:
当是数字时,对number进行变换,number = number*10+c-‘0’(因为number可能不止一位,可能连续出现多位number);
当是字母时,将字母加入val;
当是 ’ [ ’ ,将number和val分别入栈,并且将number和val初始化(为什么要初始化?因为字符串中不止存在一个 [ ],遇到新的括号时,入栈的数字和字母与之前的没有一点关系);
当时 ’ ] ’ ,出栈,并进行字符串的变换操作。

代码

class Solution {
    public String decodeString(String s) {
		int number = 0;
		Stack<Integer> n_Stack = new Stack<>();
		Stack<StringBuffer> w_Stack = new Stack<>();
		StringBuffer val = new StringBuffer();
		for(Character c : s.toCharArray()) {//遍历每一个字符
			if(Character.isDigit(c)) {
				number = number*10+c-'0';
			}else if(Character.isLetter(c)) {
				val.append(c);
			}else if(c == '[') {
				n_Stack.push(number);
				number = 0;
				w_Stack.push(val);
				val = new StringBuffer();
			}else {
				StringBuffer ss = new StringBuffer();
				ss.append(w_Stack.pop());
				int n = n_Stack.pop();
				for(int i=0;i<n;i++) {
				/*
				 * [ ] 里面的字符并没有入栈的,此时val的值就是[ ]中间的值
				 *对val进行复制操作,并将重复变换后的val的值放在出栈字符的后面组成新的val参与变换
				 */
					ss.append(val);
				}
				val = ss;
			}
		}
		return val.toString();
    }
}

相关知识

Java Character类
Java Character.isLetter() 方法,判断字符是否为字母
Java Character.isDigit() 方法,判断字符是否为数字
Java Character.isWhitespace() 方法,判断字符是否为空白字符
Java Character.isUpperCase() 方法,判断字符是否为大写字母
Java Character.isLowerCase() 方法,判断字符是否为小写字母
Java Character.toUpperCase() 方法,将小写字符转换为大写。
Java Character.toLowerCase() 方法,将大写字符转换为小写。
Java Character.toString() 方法,char字符转换成string
Java Character.getNumericValue() Unicode字符int值

你可能感兴趣的:(leetcode数据结构之栈,java)