赞
踩
给定一段"密文"字符串s
,其中字符都是经过"密码本"映射的,现需要将"密文"解密并且输出。
映射的规则 :"a-i"
分别用"1-9"
表示,"j-z"
分别用"10*-26*"
表示
约束:映射始终唯一
“密文”字符串
明文字符串
翻译后的文本的长度在100
以内
20*19*20*
tst
本题需要分两步走:对原字符串的预处理以及元素映射关系。
涉及元素一一映射的关系,构建从数字到字母的映射这件事,很容易想到应该使用哈希表来解决。
另外,本题所给密码字符串中,两位数(10-26
)的后面都会带一个*
,而一位数(1-9
)的后面不带*
,我们必须把这两种情况区分开来。
如果我们从头到尾地遍历原字符串s
,每次遇到一个*
号,则说明此时*
号前面的两个字符需要合并在一起,视为一个两位数来处理。
很显然,只有在遇到*
号的时候,才需要去查看刚刚最新遇到的两个数字字符,这是一种后进先出的思路,很显然可以使用栈来处理这个过程。
退出循环后,栈中储存了若干个数字字符串(有一位数也有两位数),再将这些数字字符串传入哈希表中进行从数字到字母的映射,再合并为一个字符串输出即为答案。
- #include <iostream>
- #include <unordered_map>
- #include <stack>
- #include <string>
-
- using namespace std;
-
- int main() {
- // 构建数字和字母之间的映射关系
- unordered_map<string, char> dic;//(1,a)(2,b)
- for (int i = 1; i <= 26; i++) {
- dic[to_string(i)] = 'a' + i - 1;
- }
-
- string s;
- cin >> s;
-
- // 构建一个栈
- stack<string> stack;
-
- // 遍历s中所有字符
- for (char ch : s) {
- // 如果是*号,说明*前面的两个数字要合并为一个两位数一起考虑
- if (ch == '*') {
- // 弹出栈顶两个元素,分别是个位和十位的字符串
- // 先弹出个位,再弹出10位
- string digit_1 = stack.top();
- stack.pop();
- string digit_10 = stack.top();
- stack.pop();
- // 将合并后的两位数重新压回栈顶
- stack.push(digit_10 + digit_1);
- }
- // 如果不是*号,而是数字,则直接入栈
- else {
- stack.push(string(1, ch));
- }
- }
-
- // 最后栈中的所有元素即为数字字符串,使用dic进行从数字到字母的映射之后再合并即可
- string result = "";
- while (!stack.empty()) {
- string numStr = stack.top();
- stack.pop();
- result = dic[numStr] + result;
- }
-
- // 输出结果
- cout << result << endl;
-
- return 0;
- }
时间复杂度:O(N)
。需要一次遍历字符串s
空间复杂度:O(N)
。哈希表所占空间,长度为26
,可视为常数级别空间;栈所占空间最大为N
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。