P1928 外星密码 题解
本题有两种方法,一种是纯模拟的思想,一种是递归思想。
$\color{green}{方法}$ $\color{green}{1:字符串处理}$
我们需要操作的对象是方括号内的部分,对于方括号外面的内容,我们不需要进行任何的操作,因此我们要找到最内层的括号,并进行处理。处理完了之后,我们把原来的进行替换。这样一直重复,直到没有括号为止,我们就得到了最终的答案。
例如下面这个数据:
1 | AC[3[3AK]] |
上述数据中,最内层的括号组为 [3AK]
,而我们可以发现,最内层的左括号是整个字符串最右边的左括号,右括号则是整个字符串最左边的右括号。因此我们只需要写一个循环,找到这两个字符即可。
我们先查找左括号:
1 | int l=-1; // l 保存左括号的位置 |
而与之相匹配的右括号必定在左括号的右边,所以搜索范围从 $[0,|str|)$ 变为 $[l,str)$,即:
1 | int r=-1; // r 保存右括号的位置 |
假如有括号存在,那么被处理的部分则是 $(l,r)$,即两个括号之间(不含括号)的部分。取其子串:
1 | string ns=""; // 初始赋值为空 |
string.replace(start,len,str)
用法:
从 start
这个位置开始,取长度为 len
的字符串,将其替换为 str
。
在这个时候,因为区间为 $(l,r)$,即 $[l+1,r-1]$,所以长度为 $r-l+1$。而替换的是这一段处理之后的内容,用一个名为 rep
的函数实现。
接下来我们要完成 rep
函数的实现:
$\color{red}{\text{Step}}$ $\color{red}{0:}$ $\color{red}{初始化}$
将 s
设为函数参数(字符串类型),t
为分离的数字,x
为分离出来的字符串。
$\color{red}{\text{Step}}$ $\color{red}{1:}$ $\color{red}{分离数字}$
我们在整个字符串 s
中处理即可,即区间为 $[0,|s|)$。思路如下:
代码:
1 | for(int i=0;s[i];i++) |
$\color{red}{\text{Step}}$ $\color{red}{2:} $\color{red}{分离字符串}$
类比分离数字的方法,我们可以用相似的方式处理:
代码:
1 | for(int i=s.size()-1;i>=0;i--) |
$\color{red}{\text{Step}}$ $\color{red}{3: 拼接}$
新建一个字符串 y
,保存拼接的内容,总共包含 t
个 x
字符串。进行拼接:
1 | while(t--)y+=x; // 往 y 中加入 t 个 x |
完整代码:
1 |
|
$\color{green}{方法}$ $\color{green}{2:递归}$
本题同样可以使用递归的算法:
主函数只需调用递归函数即可,因为递归函数既实现输入,又实现了字符串的处理。
完整代码:
1 |
|
P1928 外星密码 题解