这题主要是栈的应用,一开始想写递归的,写到一半发现自己写不下去了,改成直接用栈...
思路就是把字符串压到两个栈里边,一个栈记录的是字母和'|'序列,另一个栈记录的是'['和数字字符序列。对一个输入的字符串遍历,步骤如下:
- 当前字符是'['或数字字符,压到栈a
- 当前字符是字母或'|',压到栈b
- 当前字符是']',进行如下操作:
- 弹出栈a直到遇到'[',并且记录重复次数num
- 弹出栈b直到遇到'|',记录字符串序列tmp
- 将重复num的tmp压入栈a中
思路看起来是很简单的,具体的做法其实还有一点繁琐,我这里用了一些调用的函数啥的。。。现在Clion上边写了一下:
#include <bits/stdc++.h>
using namespace std;
stack<char> st,sa;
string s;
int main() {
cin>>s;
string res;
for (int i = 0; i < s.size(); ++i) {
// cout<<"ch:"<<s[i]<<endl;
if (s[i]=='['|| isdigit(s[i])){
st.push(s[i]);
}else if (s[i]=='|' || isalpha(s[i])){
sa.push(s[i]);
}else if (s[i]==']'){
int num=0;
int ten=1;
while(st.top()!='['){
// cout<<"st.top:"<<st.top()<<endl;
num=ten*(st.top()-'0')+num;
st.pop();
ten*=10;
}
// cout<<"num:"<<num<<endl;
st.pop();
string tmp;
while(sa.top()!='|'&&!sa.empty()){
tmp+=sa.top();
sa.pop();
}
// cout<<"tmp:"<<tmp<<endl;
reverse(tmp.begin(),tmp.end());
// cout<<"reverse tmp:"<<tmp<<endl;
if (!sa.empty()) sa.pop();
string t;
for (int j = 0; j < num; ++j) {
t+=tmp;
}
// cout<<"t:"<<t<<endl;
for (int j = 0; j < t.size(); ++j) {
sa.push(t[j]);
}
}
}
while(!sa.empty()){
res+=sa.top();
sa.pop();
}
reverse(res.begin(),res.end());
cout<<res<<endl;
return 0;
}
//HG[3|B[2|CA[10|G]]]F
确认结果没错就交了,然后也通过所有样例了:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @return string字符串
*/
stack<char> st,sa;
string compress(string str) {
string s=str;
string res;
for (int i = 0; i < s.size(); ++i) {
// cout<<"ch:"<<s[i]<<endl;
if (s[i]=='['|| isdigit(s[i])){
st.push(s[i]);
}else if (s[i]=='|' || isalpha(s[i])){
sa.push(s[i]);
}else if (s[i]==']'){
int num=0;
int ten=1;
while(st.top()!='['){
// cout<<"st.top:"<<st.top()<<endl;
num=ten*(st.top()-'0')+num;
st.pop();
ten*=10;
}
// cout<<"num:"<<num<<endl;
st.pop();
string tmp;
while(sa.top()!='|'&&!sa.empty()){
tmp+=sa.top();
sa.pop();
}
// cout<<"tmp:"<<tmp<<endl;
reverse(tmp.begin(),tmp.end());
// cout<<"reverse tmp:"<<tmp<<endl;
if (!sa.empty()) sa.pop();
string t;
for (int j = 0; j < num; ++j) {
t+=tmp;
}
// cout<<"t:"<<t<<endl;
for (int j = 0; j < t.size(); ++j) {
sa.push(t[j]);
}
}
}
while(!sa.empty()){
res+=sa.top();
sa.pop();
}
reverse(res.begin(),res.end());
return res;
}
};
当然,也有一篇很好的递归的java写法可以参考: