给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例:
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
第一次提交代码:
class Solution { public: string decodeString(string s) { stack<char> stk; string res; int i=0; while (i<s.size()){ if (s[i] == '['){ ++i; while(s[i] != ']'){ stk.push(s[i]); ++i; } string tmp; while (stk.top() != '['){ tmp = tmp.insert(0, 1, stk.pop()); } int n = int(stk.pop()); for (int j=0; j<n; ++j) res = res + tmp; continue; } if (s[i]>='0' && s[i]<='9'){ stk.push(s[i]); ++i; continue; } res = res + s[i]; } return res; } };
问题1 对模板不熟悉,肯定有不少错误
问题2 对于嵌套情况没有处理,逻辑上有错误。
关键还是对C++模板编程不熟,丧失了继续思考的动力,开始看别人的AC代码
参考@YouLookDeliciousC代码,提交自己代码:
class Solution { public: string decodeString(string s) { stack<string> str_stack; stack<int> num_stack; string tmp; int i=0, count = 0;; while (i<s.size()){ if (s[i]>='0' && s[i]<='9'){ count = count * 10 + (s[i]-'0'); ++i; continue; } if (s[i] == '['){ num_stack.push(count); count = 0; //str_stack.top() = str_stack.top() + tmp; str_stack.push(tmp); tmp = ""; ++i; continue; } if (s[i] == ']'){ for (int j=0; j<num_stack.top(); ++j){ str_stack.top() = str_stack.top() + tmp; } tmp = str_stack.top(); num_stack.pop(); str_stack.pop(); ++i; continue; } tmp = tmp + s[i]; ++i; } return tmp; } };
通过之前,有一个bug:
if (s[i]>='0' && s[i]<='9'){ count = count * 10 + int(s[i]);
可能是python写多了,导致这样的语法,调试结果出来一大堆“aaaaaaa……”,用vs2012调试后发现“3”变为了51,原来是吧‘3’的asc码直接转化。
while-continue 代码很冗杂,再次对比@YouLookDeliciousC代码后改用for循环控制。
class Solution { public: string decodeString(string s) { stack<string> str_stack; stack<int> num_stack; string tmp; int count = 0; for (int i=0; i<s.size(); ++i){ if (s[i]>='0' && s[i]<='9'){ count = count * 10 + (s[i]-'0'); } else if (s[i] == '['){ num_stack.push(count); str_stack.push(tmp); count = 0; tmp = ""; } else if (s[i] == ']'){ for (int j=0; j<num_stack.top(); ++j){ str_stack.top() = str_stack.top() + tmp; } tmp = str_stack.top(); num_stack.pop(); str_stack.pop(); } else tmp = tmp + s[i]; } return tmp; } };
// 我认为这个代码已经精简到了简无可简。
因为不知道字符是不是全为字母,所以if-else放在最后。
总结:
1、本题属于数据结构栈的经典题、基本题;
2、收获:
- char型字符转int:
int count = 0; for (int i=0; i<string.size(); ++i) if (s[i]>=0 && s[i]<=9) count = count * 10 + (s[i] - '0');
搜了一下库函数操作讲解很多,有机会接着看;
- C++ STL中stack的使用
stack<string> str_stack;
stack.push()
stack.pop(); 注意stack.pop()不返回任何值。
stack.top()