洛谷 P1928 外星密码 题解

题目链接

题干:

​ 比较简单,就是类似于对一个字符串:ABC[3LM][2[2HJ]],将被解压缩为ABCLMLMLMHJHJHJHJ,就是给一个原始字符串,得到解压后的字符串。

思路:

​ 这题就是一个比较简单的递归,我使用栈实现。每次读入字符都放入栈中,如果遇到],那么将会从栈中逐渐读取字符,组成一个临时的字符串,直到读到数字,把数字提取出来后,再根据数字这个倍数,把临时字符串扩充,然后再放入栈中。

​ 代码如下:

#include<bits/stdc++.h>
using namespace std;

int main()
{
    string s;
    char word, temp[20005];
    cin>>s;
    stack<char> res;

    int size = s.size(), j, num, order;
    for (int i = 0; i < size; ++i)
    {
        word = s[i];
        if (word != ']')
            res.push(word);
        else  // 如果获取到了 ]
        {
            j = -1;
            // 从stack中把字符拿出来,放到temp中
            word = res.top();;
            res.pop();
            while (word < '0' || word > '9')  // 如果没拿到数字
            {
                temp[++j] = word;
                word = res.top();
                res.pop();
            }
            // 如果拿到了数字  开始提取数字
            num = word - '0';
            order = 10;
            word = res.top();
            res.pop();
            while (word != '[')
            {
                num += (order * (word - '0'));
                order *= 10;
                word = res.top();
                res.pop();
            }
            // 如果遇到了闭合符号 [
            // num是重复次数  temp最后一个字母的index是j
            for (int p = 0; p < num; ++p)
            {
                for (int y = j; y >=0; --y)
                    res.push(temp[y]);
            }
        }
    }

    j = -1;
    while (!res.empty())
    {
        word = res.top();
        res.pop();
        temp[++j] = word;
    }

    for (int i = j; i >= 0; --i)
        printf("%c", temp[i]);

    return 0;
}

​ 但是这里我没有处理这种情况:AS[2[VB3[HJ]]],这里解压后变成ASVBHJHJHJVBHJHJHJ。我的代码默认从栈中获取数字后,接着就会获取到[,也就是没考虑到该例子中的VB这种情况。但是一样能过。。。

递归方法:

​ 直接看别人的题解

#include<bits/stdc++.h>
using namespace std;
string read()
{
	int n;
	string s="",s1;
	char c;
	while (cin>>c)//一直读入字符,直到Ctrl+z
	{
		if (c=='[')
		{
			cin>>n;//读入D
			s1=read();//读入X
			while (n--) s+=s1;//重复D次X
            //注:上面不能写成while (n--) s+=read();
		}
		else 
		{
			if (c==']') return s;//返回X
		    else s+=c;//如果不是'['和']',那就是X的一个字符,所以加进X
		}
	}
}
int main()//巨短主函数
{
	cout<<read(); 
	return 0;
}

​ 可以看到就是递归调用了read()函数。

一点问题

​ 递归的代码里,对于一个字符串325SFFS,好像直接int n; cin>>n;就能把数字325读入,并且还能继续从字符S开始读入。

​ 测试:

#include<bits/stdc++.h>
#include <sstream>

using namespace std;

int main()
{
    string s("aa45sfjsljfls");

    std::stringstream stream;
    
    stream<<s;

    char c;
    stream>>c;
    cout<<c<<endl;
    stream>>c;
    cout<<c<<endl;

    int n;
    stream>>n;
    cout<<n<<endl;

    stream>>c;
    cout<<c<<endl;

    return 0;
}

结果:

a
a
45
s
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值