- 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”
这是自己的狗屎东西。
package PTA;
import sun.awt.SunHints;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
// BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int t[] = new int[]{1,3,4,2,2};
int ans =0;
for(int i=1;i<=100;i++){
ans +=i;
}
new Main().decodeString("3[a]2[bc]");
System.out.println(new Main().decodeString("3[a2[c]]"));
}
public String decodeString(String s) {
Deque<Integer> stack = new ArrayDeque<>();
StringBuffer ans = new StringBuffer();
for(int i=s.length()-1;i>=0;i--){
if(s.charAt(i)==']'){
int j=i-1;
StringBuffer sb=new StringBuffer();
StringBuffer sbnum=new StringBuffer();
while(s.charAt(j)!='['){
sb.append(s.charAt(j));
j--;
}
sb.reverse();//因为是先存的后面要reverse一下
j--;
while(j>=0 && s.charAt(j)>='0' && s.charAt(j)<='9'){
sbnum.append(s.charAt(j));
j--;
}
i=j+1;//此时i正好对应数字
for(int w=0;w<Integer.parseInt(sbnum.reverse().toString());w++){
ans.insert(0,sb);
}
}
}
return ans.toString();
}
}
题解的
class Solution {
int ptr;
public String decodeString(String s) {
LinkedList<String> stk = new LinkedList<String>();
ptr = 0;
while (ptr < s.length()) {
char cur = s.charAt(ptr);
if (Character.isDigit(cur)) {
// 获取一个数字并进栈
String digits = getDigits(s);
stk.addLast(digits);
} else if (Character.isLetter(cur) || cur == '[') {
// 获取一个字母并进栈
stk.addLast(String.valueOf(s.charAt(ptr++)));
} else {
++ptr;
LinkedList<String> sub = new LinkedList<String>();
while (!"[".equals(stk.peekLast())) {
sub.addLast(stk.removeLast());
}
Collections.reverse(sub);
// 左括号出栈
stk.removeLast();
// 此时栈顶为当前 sub 对应的字符串应该出现的次数
int repTime = Integer.parseInt(stk.removeLast());
StringBuffer t = new StringBuffer();
String o = getString(sub);
// 构造字符串
while (repTime-- > 0) {
t.append(o);
}
// 将构造好的字符串入栈
stk.addLast(t.toString());
}
}
return getString(stk);
}
public String getDigits(String s) {
StringBuffer ret = new StringBuffer();
while (Character.isDigit(s.charAt(ptr))) {
ret.append(s.charAt(ptr++));
}
return ret.toString();
}
public String getString(LinkedList<String> v) {
StringBuffer ret = new StringBuffer();
for (String s : v) {
ret.append(s);
}
return ret.toString();
}
}
看了题解自己写的,还是发现了很多问题
例如:栈中栈顶现在存的是’abc‘,其下面一个存的是‘x’,现在要将其取出来,在我们的代码中,取出来便是’abc‘,由于是由栈顶开始取的,所以取出来的是abcx,但是实际输出应该是xabc。
所以我们采取了反转一下来解决这个问题:
但是我们此时如果查看输出的话,其输出是xcba!!出问题了,所以在从栈中取出元素时,就要先反转一下,如果是多位字符串不反转就要出现上面‘’abc‘的问题,先反转一下,最后循环结束后再反转一下就可以了
用注释掉的代码就要出问题。!!题解的getStirng方法就是为了避免这个问题。
tem.append(new StringBuffer(stack.pop()).reverse());
// tem.append(stack.pop());
该题还需要注意的是:在遍历字符串s的时候,其数字有可能是多位数例如:13[a],我们是需要读取13为数字!所以在进行数字判断时要注意!(最开始的狗屎代码也想到了,但是总是哪出问题改哪里,越改越乱,应该按照最开始的大体思路来!)
class Solution {
public String decodeString(String s) {
Deque<String> stack = new ArrayDeque<>();
int index =0;
while(index < s.length()){
char ch = s.charAt(index);
//如果当前字符是数字
if(Character.isDigit(ch)){
StringBuffer t = new StringBuffer();
t.append(ch);
index++;
//判断是否为多位数
while(Character.isDigit(s.charAt(index))){
t.append(s.charAt(index));
index++;
}
//t不用反转
stack.push(t.toString());
}else if(Character.isLetter(ch) || ch=='['){
//如果当前字符是字母(包括大写和小写字母)或 '['
stack.push(ch+"");
index++;
}else{
//如果当前字符是']'
StringBuffer tem = new StringBuffer();
while(!stack.isEmpty() &&!stack.peek().equals("[")){
//当是字母且stack不为空时,就加入到tem中
//其实也可以不用判断为空,因为其输入格式必为: 3[a] 这种形式,必定数字先进栈再是[进栈,所以判断时栈中必定有[
tem.append(new StringBuffer(stack.pop()).reverse());
// tem.append(stack.pop());
}
//反转一下顺序
tem.reverse();
//当前stack匹配到的是[,[前一个必定为数字,现在我们要提出数字
stack.pop();//删除[,现在栈顶便是数字
StringBuffer t = new StringBuffer();
for(int w =0;w<Integer.parseInt(stack.peek());w++){
t.append(tem);
}
//删除栈顶数字
stack.pop();
stack.push(t.toString());
index++;
}
}
StringBuffer ans = new StringBuffer();
//这种方式是默认从栈顶进行遍历,但是栈底的字符串应该先输出,故该方式不行
// for(String t : stack){
//
// ans.append(t);
// }
while(!stack.isEmpty()){
ans.append(stack.removeLast());//栈顶表示first,栈底表示last
}
return ans.toString();
}
}