29. 邮件解密

某一天,郭老师收到一封离奇的邮件,邮件内容为一大段的字符串文本(字符个数多达 100000 个),他完全看不懂这封邮件想表达什么意思,于是他找到一位密码学大神帮忙,为了留存神秘感,密码大神并没有告诉郭老师最终的答案,只告诉他要按照一些规则进行解密,首先开启两封空邮件 t 和 u,随后可进行两种操作:

  1. 在原始邮件内容 s 中,提取第一个字符,放到邮件 t 的末尾
  2. 在邮件 t 内,提取最后一个字符,放到邮件 u 的末尾

当邮件 s 和 t 均为空且邮件 u 中的内容字典序最小时,得到的 u 即为解密后的邮件。现在请你帮忙写程序解决此问题。

输入

输入包含多个测试用例,对于每个测试用例,输入一行非空的且全部由小写字母组成的邮件文本 s ( 1  ≤  |s|  ≤  100000 )。

输出

对于每个测试用例,输出一行解密后的邮件 u。

测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. cab↵
  2. acdb↵
  3. a↵
  4. ab↵
  5. ba↵
以文本方式显示
  1. abc↵
  2. abdc↵
  3. a↵
  4. ab↵
  5. ab↵
1秒64M0


//AC 讨论区里朱杰大佬给的思路
//循环操作s数组,每次取出一个,加入到t数组的结尾,然后在对应记录字母个数的结构体里把这个字母的个数减一。
//然后判断t的结尾(也就是栈头元素),如果在s的后面还有比这个元素小的元素(这可不是扫一遍s数组,不然会t连妈妈都不认识的。
//注意了,就是扫一遍你的记录字母个数的那个结构体数组,从a扫到当前元素,如果中间有不是0的,
//那么就是成立,也就是要continue<就是接下来几句话),
//那么就continue,否则就进行下一步操作。
//那么,下一步怎么操作呢?老规矩,循环模拟栈的实现过程(看起来很高大上,其实就是个水一水的数组实现)。
//从t数组的尾部循环取元素,用我刚才说的方法判断,如果s后面有元素 比当前元素小,就直接弹出循环,否则就加入u数组,继续循环。
//这样,通过一条龙操作就可以把s数组中的所有字母全部放到t和u里面,然后就倒序输出t,顺序输出u就可以了。
#include<stdio.h>
#include<string.h>

int main()
{
	int ch;
	while (1)
	{
		char Str_S[100005] = { '\0' };
		int S_len = 1;
		int T_Num = 0;
		int strmap[28] = { 0 };
		//输入部分
		ch = getchar();
		if (ch < 0)
			break;
		Str_S[0] = ch;
		strmap[ch - 'a']++;
		for (int i = 1;; i++)
		{
			ch = getchar();
			if (ch == 10)
				break;
			S_len++;
			Str_S[i] = ch ;
			strmap[ch - 'a']++;
		}
		//开始操作
		char Str_T[100005] = { '\0' }, Str_U[100005] = { '\0' };
		int ans = 0, xx = 0;
		for (int i = 0;i<S_len; i++)
		{
			Str_T[T_Num++] = Str_S[i];
			int kk = Str_S[i] - 'a';
			strmap[kk]--;
			for (int i = 0; i < kk; i++)
			{
				if (strmap[i] > 0)
				{
					ans = 1;
					break;
				}
			}
			if (ans == 1)
			{
				ans = 0;
				continue;
			}	
			for (int i = T_Num-1;i>=0; i--)
			{
				int kkk = Str_T[i] - 'a';
				for (int i = 0; i < kkk; i++)
				{
					if (strmap[i] > 0)
					{
						ans = 1;
						break;
					}	
				}
				if (ans == 1)
				{
					ans = 0;
					break;
				}
				Str_U[xx++] = Str_T[i];
				Str_T[i] = '\0';
				T_Num--;
			}
		}
		for (int i = 0; Str_U[i] != '\0'; i++)
			printf("%c", Str_U[i]);
		for (int i = T_Num - 1; i >= 0; i--)
			printf("%c", Str_T[i]);
		printf("\n");
	}
	return 0;
}









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值