牛客网:压缩算法

这题主要是栈的应用,一开始想写递归的,写到一半发现自己写不下去了,改成直接用栈...

思路就是把字符串压到两个栈里边,一个栈记录的是字母和'|'序列,另一个栈记录的是'['和数字字符序列。对一个输入的字符串遍历,步骤如下:

  1. 当前字符是'['或数字字符,压到栈a
  2. 当前字符是字母或'|',压到栈b
  3. 当前字符是']',进行如下操作:
  • 弹出栈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写法可以参考:

牛客编程题-压缩算法问题-递归解法_hygge_fff的博客-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值