2015网易游戏笔试02

4 篇文章 0 订阅
3 篇文章 0 订阅

题目链接

题目大意:
给定一个压缩后的字符串,求其解压缩之后的长度。

两个存储的规则:

(1)如果字符串中有连续相同的大写字母,它们可以选择用”字符+出现次数”的方式替代。如字符串’AABCCCCDD’,可以用’A2BC4D2’表示,也可以用’A2BC2C2DD’表示。

(2)如果字符串中有连续出现的模式串(模式串长度大于1),它们可以选择用”(模式)+出现次数”的方式替代。如字符串’FABCABCABCE’,可以用’F(ABC)3E’表示,也可以用’F(ABC)2ABCE’表示。

上述规则中的”连续”均指出现次数大于1,规则(2)中的括号后一定是一个大于1的数值,代表出现次数。

综合上述两个规则,字符串’AABAABFAABAABFG’可以用’((A2B)2F)2G’表示。小Y保证输出的压缩串符合上述的两个规则,以下类型的非法字符串不会出现:

‘(A)5’: 括号冗余

‘A1A4’: 数字1冗余

‘A((AA))2’: 括号冗余

(ABC)1: 括号和数字1冗余

对于给定的一个用上述规则压缩后的字符串,对应的原串是唯一的。小Y想知道这个字符串原来的长度是多少,以此计算压缩倍率。你能帮助他吗?

样例:

样例输入
4
(AA)2A
((A2B)2)2G
WANGYI
A2BC4D2
样例输出
5
13
6
9

思路:

维护一个栈,

  1. 遇到 ‘(’ 将当前累计长度先压栈,
  2. 遇到 ‘)’则需要考虑其后面的数字串 ,将当前长度乘倍,并且将 栈顶元素出栈,累加到当前的长度上,
  3. 遇到A-Z,将当前长度 +1
  4. 遇到数字,代表前一个字符乘倍

代码:

#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
//fstream resource("/Users/bingoboy/Downloads/cases.txt");
int cnt;
string tmp;
stack<int> cstack;
char buf[110];

int main(){
    int T;
    cin>>T;
    while(T--){
        scanf("%s",buf);
        int cur=0,mul=0;
        stack<int> ntk;
        for(int i=0;buf[i];){
            if(buf[i]=='(') { // CASE 1
                ntk.push(cur);
                cur=0;mul=0;
                i++;
            }else if(buf[i]==')'){ //  CASE 2
                if(isdigit(buf[i+1])){
                    int j=i+1;
                    while(isdigit(buf[j])){
                        mul=mul*10 + buf[j]-'0';
                        j++;
                    }
                    cur*=mul; mul=0; // 当前长度乘倍
                    i=j;
                }else{
                    i++;
                }
                cur+=ntk.top(); ntk.pop();  //栈顶元素出栈 ,累加到当前长度
            }else if(isdigit(buf[i])){  // CASE 4
                int j=i;
                while(isdigit(buf[j])){
                    mul=mul*10 + buf[j]-'0';
                    j++;
                }
                cur+=mul-1; mul=0;   //前一个字符乘倍
                i=j;
            }else{          //CASE3
                cur++;
                i++;
            }
        }
        cout<<cur<<endl;
    }
    return 0;

}
/*
int parentheses(string & aa){
    if (aa.empty()) {
        return 0;
    }
    int fcnt = 0;
    int amount = 0;
    for (int i = 0; i < aa.size(); ++i) {

        if (aa[i] == '(') {
            cstack.push(fcnt);
            fcnt = 0;
            cstack.push(-1);
            continue;
        }

        if (aa[i] == ')') {
            ++i;
            while (aa[i] <= '9' && aa[i] >= '0') {
                amount = amount*10 + aa[i] - '0';
                i ++;
            }
            i--;
            cstack.pop();
            fcnt = amount * fcnt + cstack.top();
            amount = 0;
            cstack.pop();
            continue;
        }

        while (aa[i] <= '9' && aa[i] >= '0') {
            amount = amount*10 + aa[i] - '0';
            i ++;
        }
        if (amount > 0) {
            fcnt += amount - 1;
            i --;
            amount = 0;
            continue;
        }

        fcnt += 1;
    }
    return fcnt;
}


int main(int argc, const char * argv[]) {
    cin >> cnt;
    while (cnt --) {
        cin >> tmp;
        cout << parentheses(tmp) << endl;
    }
    return 0;
}
*/

扫码关注作者,定期分享技术、算法类文章
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值