逐字符将英文字母后移一位,并分别处理小写与大写字母的循环边界。
OJ: noi_openjudge
题目 ID: ch0107-09
难度:入门
标签:字符串模拟python
创建: 2026-07-30 23:01
更新: 2026-07-31 11:59
后置题目
roj 3598[NOIP2012-提高] Vigenère 密码A 教的「字母平移后字母表回绕」这一步被 B 的解密公式逐位复用,只是把固定 +1 换成密钥位偏移并补上 i % len(key) 密钥循环与大小写跟随密文roj 1402Vigenère密码A 教的是字母序号平移并在字母表末尾回绕,B 的减法解密正是把这一步按位复用(mod 26 回绕),再叠加密钥循环取位与大小写跟随密文。noi_openjudge ch0112-08Vigenère密码B 把 A 的「字母按字母表循环移位、越过 z/Z 回绕」这一步推广成任意位移模 26 并按大小写选 ASCII 基准,逐字符映射的处理框架完全相同
题意
将字母替换为字母表后继,z 循环到 a,Z 循环到 A,其他字符不变。
思路
普通字母可用 ASCII 码加一;z、Z 是循环边界,要单独映射。生成器逐字符调用 encrypt 后拼接输出。
代码
Python代码
python
def encrypt(character: str) -> str:
if "a" <= character <= "y" or "A" <= character <= "Y":
return chr(ord(character) + 1)
if character == "z":
return "a"
if character == "Z":
return "A"
return character
print("".join(encrypt(character) for character in input()))C++代码
cpp
#include <cstdio>
#include <cstring>
#define maxn 500
int n;
char str[maxn];
int idx = 1;
char _map[maxn];
int main(){
char t;
int i;
for (i='a';i<='z';i++){
_map[i] = i+1;
}
_map['z'] = 'a';
for (i='A';i<='Z';i++){
_map[i] = i+1;
}
_map['Z'] = 'A';
while(1){
int ans = scanf("%c",&t);
if( t== '\n' || t == '\r' || ans == EOF)
break;
str[idx] = t;
idx++;
}
idx--;
for (i=1;i<=idx;i++){
char c = str[i];
if( ( c >='a' && c <='z') ||( c >='A' && c <='Z') )
printf("%c",_map[c]);
else
printf("%c",c);
}
return 0;
}复杂度
时间复杂度和输出空间均为
总结
字符平移题最重要的边界是字母表末尾的回绕。