#P2253. 第2题-解密字符串
-
1000ms
Tried: 70
Accepted: 35
Difficulty: 3
所属公司 :
华为
时间 :2024年11月6日-留学生
-
算法标签>模拟
第2题-解密字符串
题目描述
给定一个加密字符串 S,需要按照以下规则对其进行解密并输出。
解密规则:
-
字母字符:若当前字符为字母
A-Z、a-z,无需解密,原样输出。 -
括号表达式:若当前字符为
'(',则其后会跟两个正整数x、y,以及一个右括号')',其中正整数x和y之间以逗号分隔。你需要从当前解密串的末尾向前数第x个字符开始,复制长度为y的字符串并追加到解密结果中。
需要注意的是,如果 y 大于可复制的字符数,则需要多次复制,直到复制满 y 个字符。复制过程中,解密串的长度会增加,这会影响后续的复制操作。
思路
模拟,枚举原始字符串碰到括号进行substr操作即可。
具体模拟步骤
-
逐字符处理:遍历输入字符串,对于每个字符,按照规则处理。
-
解析括号表达式:当遇到
'('时,需要解析出两个整数x和y。 -
处理复制操作:
- 计算复制的起始位置:
pos = res.length() - x。 - 复制长度为
y的字符串,如果剩余可复制的字符数不足y,则需要多次复制,直到复制满y个字符。
- 计算复制的起始位置:
-
更新解密结果:在复制过程中,解密结果
res的长度会增加,需要动态更新。
cpp
#include <iostream>
#include <string>
int main() {
std::string s; // 输入的加密字符串
std::getline(std::cin, s);
std::string res; // 解密后的结果字符串
for (size_t i = 0; i < s.length(); ++i) {
if (s[i] == '(') {
// 解析 x 和 y
int x = 0, y = 0;
++i; // 跳过 '('
// 解析 x
while (s[i] != ',') {
x = x * 10 + (s[i] - '0');
++i;
}
++i; // 跳过 ','
// 解析 y
while (s[i] != ')') {
y = y * 10 + (s[i] - '0');
++i;
}
// 进行复制操作
int pos = res.length() - x; // 复制的起始位置
while (y > 0) {
int len = std::min((int)res.length() - pos, y); // 本次可复制的长度
res += res.substr(pos, len); // 追加复制的字符串
y -= len; // 更新剩余需要复制的长度
}
} else {
// 字母字符,直接添加到结果中
res += s[i];
}
}
// 输出解密后的字符串
std::cout << res << std::endl;
return 0;
}
python
s = input()
res = ''
i = 0
while i < len(s):
if s[i] == '(':
i += 1 # 跳过 '('
x = 0
while s[i] != ',':
x = x * 10 + int(s[i])
i += 1
i += 1 # 跳过 ','
y = 0
while s[i] != ')':
y = y * 10 + int(s[i])
i += 1
i += 1 # 跳过 ')'
pos = len(res) - x # 复制的起始位置
while y > 0:
length = min(len(res) - pos, y) # 本次可复制的长度
res += res[pos:pos+length] # 追加复制的字符串
y -= length # 更新剩余需要复制的长度
else:
res += s[i]
i += 1
print(res)
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuilder res = new StringBuilder();
int i = 0;
while (i < s.length()) {
if (s.charAt(i) == '(') {
i++; // 跳过 '('
int x = 0;
while (s.charAt(i) != ',') {
x = x * 10 + (s.charAt(i) - '0');
i++;
}
i++; // 跳过 ','
int y = 0;
while (s.charAt(i) != ')') {
y = y * 10 + (s.charAt(i) - '0');
i++;
}
i++; // 跳过 ')'
int pos = res.length() - x; // 复制的起始位置
while (y > 0) {
int len = Math.min(res.length() - pos, y); // 本次可复制的长度
res.append(res.substring(pos, pos + len)); // 追加复制的字符串
y -= len; // 更新剩余需要复制的长度
}
} else {
res.append(s.charAt(i));
i++;
}
}
System.out.println(res.toString());
}
}
题目内容
给定一个加密字符串S,你需要按照以下规则对其解密并输出。解密规则:
1.若当前字符为字母A−Z,a−z,无需解密,原样输出。
2.若当前字符为'(',则其后会跟两个正整数x、y和一个字符')’,正整数x和y之间以逗号为分隔符,你需从当前解密串倒数第x个字符开始复制y个字符作为解密后的信息输出。
需要考虑y大于“剩余可复制字符数"的情况,此时复制需要多次完成先复制全部剩余字符输出,此时解密串的长度已变长,继续1次或者多次复制,直到复制完y个字符。参考样例1和样例2。
约束:
- 0<s.length<=1000,解密后的字符串长度<=2000
- 0<x<=99, 0<y<=99,且输入保证x不会越界,即x小于当前解密串的长度。
- 输入的字符串中只包含大小写字母和(x,y)格式子串
输入描述
输入共一行,代表加密字符串,包含大小写字母和(x,y)格式子串
输出描述
输出共一行,表示解密后的字符串,只包含大小写字母
样例1
输入
ABCDE(3,2)(2,3)
输出
ABCDECDCDC
说明
ABCDE不需要解密,原样输出。
(3,2)解密,向后退3个字符,
ABCDE
|
复制2个字符,得到ABCDECD,(3,2)解密结束;
(2,3)解密,向后退2个字符,
ABCDECD
|
只有2个字符,先复制2个字符CD,得到ABCDECDCD,
ABCDECDCD
|
继续复制1个字符C,得到ABCDECDCDC。(2,3)解密完毕。
样例2
输入
ABCD(3,8)(10,10)mn
输出
ABCDBCDBCDBCCDBCDBCDBCmn
说明
ABCD不需要解密,原样输出,
(3,8)解密,向后退3个字符,到字符B的位置
ABCD
|
先复制3个字符得到ABCDBCD,还剩下5个字符待复制
ABCDBCD
|
再复制3个字符得到ABCDBCDBCD,还剩下2个字符复制
ABCDBCDBCD
|
再复制2个字符得到ABCDBCDBCDBC,还剩下0个字符待复制,(3,8)解密结束
(10,10)解密,向后退10个字符
ABCDBCDBCDBC
|
复制10个字符得到ABCDBCDBCDBCCDBCDBCDBC,(10,10)解密结束
mn不需要解密,原样输出,解密结束,结果为:ABCDBCDBCDBCCDBCDBCDBCmn