题目的主要信息:
- 给字符串加密,输入多个明文字符串,长度不超过100,输出多次密文
- 加密方式:数字不变,对于小写字母abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9,对于大写字母变成小写字母再后移一位(z后移是a),其他字符也不变
- 密码中没有空格
方法一:多次判断法
具体做法:
对于大写字母,我们利用加1取余的方式,加上ASCⅡ码的数字来变换,比如当前字符减去'A'就带着它是26个字母中的第几个(下标0开始),右移一位即加1,对26取模即循环,最后加上'a'转化为小写字母。
对于数字我们不变。
对于小写字母,利用switch-case对其分类讨论,转化为相应的数字即可。
因此,从明文到密文,我们遍历字符串依次进行上述操作即可,注意大写转出来的小写字母不用再转成数字。
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
while(cin >> s){
for(int i = 0; i < s.length(); i++){
if(s[i] >= 'A' && s[i] <= 'Z'){ //大写字母
s[i] = (s[i] -'A' + 1) % 26 + 'a'; //后移一位,变成小写
continue;
}
else if(s[i] >= '0' && s[i] <= '9') //数字不变
continue;
else{ //小写字母开始转换
switch(s[i]){
case ('a'): case ('b'): case ('c'):
s[i] = '2'; break;
case ('d'): case ('e'): case ('f'):
s[i] = '3'; break;
case ('g'): case ('h'): case ('i'):
s[i] = '4'; break;
case ('j'): case ('k'): case ('l'):
s[i] = '5'; break;
case ('m'): case ('n'): case ('o'):
s[i] = '6'; break;
case ('p'): case ('q'): case ('r'): case ('s'):
s[i] = '7'; break;
case ('u'): case ('v'): case ('t'):
s[i] = '8'; break;
case ('w'): case ('x'): case ('y'): case ('z'):
s[i] = '9'; break;
}
}
}
cout << s << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,为字符串长度,遍历一次字符串
- 空间复杂度:,无额外空间
方法二:打表
具体做法:
我们可以对26个字母用26个数组元素来代替,每个数组元素下标对应26个字母的位数,元素就是其转化成的数字。我们小写字母转数字直接查表然后加上'0'即可。
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
int a[26] = {2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9};
while(cin >> s){
for(int i = 0; i < s.length(); i++){
if(s[i] >= 'A' && s[i] <= 'Z'){ //大写字母
s[i] = (s[i] -'A' + 1) % 26 + 'a'; //后移一位,变成小写
continue;
}
else if(s[i] >= '0' && s[i] <= '9') //数字不变
continue;
else if(s[i] >= 'a' && s[i] <= 'z'){ //小写字母开始转换
s[i] = a[s[i] - 'a'] + '0';
}
}
cout << s << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,为字符串的长度,一次遍历
- 空间复杂度:,常数级空间
方法三:正则表达式
具体做法:
我们还可以用正则表达式替换,首先依次替换字符串中的小写字母到相应的数字,然后转化大小字母为小写:先转化A-Y,通过ASCⅡ码加33即可,然后单独转换大写字母Z到小写字母a。
import re
while True:
try:
s = input().strip()
passwd = re.sub("[a-c]", "2", s)
passwd = re.sub("[d-f]", "3", passwd)
passwd = re.sub("[g-i]", "4", passwd)
passwd = re.sub("[j-l]", "5", passwd)
passwd = re.sub("[m-o]", "6", passwd)
passwd = re.sub("[p-s]", "7", passwd)
passwd = re.sub("[t-v]", "8", passwd)
passwd = re.sub("[w-z]", "9", passwd)
def high_low(matched): #从大写到小写
str_up = matched.group(0)
asc = ord(str_up) + 33 #ASCⅡ码差距33
value = chr(asc)
return str(value)
passwd = re.sub("[A-Y]", high_low, passwd)
passwd = re.sub("[Z]", "a", passwd) #替换Z
print(str(passwd))
except:
break
复杂度分析:
- 时间复杂度:,正则表达式替换复杂度都是
- 空间复杂度:,常数级空间