题意
给定一个只包含数字和大小写字母的字符串,和一个映射规则,求映射后的字符串。
其中映射规则为:
- 数字不转换
- 小写字母按照手机九宫格键盘上转换成数字
- 大写字母转换成小写字母的循环右移一位
限制:字符串长度不大于100
方法
朴素实现
本题,直接把题意转换成代码即可
代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i = (a) ;i<(b);i++)
int main(){
char pass[110];
scanf("%s",pass); // 读入
int n = strlen(pass); // 获取长度
rep(i,0,n){ // 遍历转换
if(pass[i]=='0')pass[i]='0';
else if(pass[i]=='1')pass[i]='1';
else if(pass[i]=='2')pass[i]='2';
else if(pass[i]=='3')pass[i]='3';
else if(pass[i]=='4')pass[i]='4';
else if(pass[i]=='5')pass[i]='5';
else if(pass[i]=='6')pass[i]='6';
else if(pass[i]=='7')pass[i]='7';
else if(pass[i]=='8')pass[i]='8';
else if(pass[i]=='9')pass[i]='9';
else if(pass[i]=='A')pass[i]='b';
else if(pass[i]=='B')pass[i]='c';
else if(pass[i]=='C')pass[i]='d';
else if(pass[i]=='D')pass[i]='e';
else if(pass[i]=='E')pass[i]='f';
else if(pass[i]=='F')pass[i]='g';
else if(pass[i]=='G')pass[i]='h';
else if(pass[i]=='H')pass[i]='i';
else if(pass[i]=='I')pass[i]='j';
else if(pass[i]=='J')pass[i]='k';
else if(pass[i]=='K')pass[i]='l';
else if(pass[i]=='L')pass[i]='m';
else if(pass[i]=='M')pass[i]='n';
else if(pass[i]=='N')pass[i]='o';
else if(pass[i]=='O')pass[i]='p';
else if(pass[i]=='P')pass[i]='q';
else if(pass[i]=='Q')pass[i]='r';
else if(pass[i]=='R')pass[i]='s';
else if(pass[i]=='S')pass[i]='t';
else if(pass[i]=='T')pass[i]='u';
else if(pass[i]=='U')pass[i]='v';
else if(pass[i]=='V')pass[i]='w';
else if(pass[i]=='W')pass[i]='x';
else if(pass[i]=='X')pass[i]='y';
else if(pass[i]=='Y')pass[i]='z';
else if(pass[i]=='Z')pass[i]='a';
else if(pass[i]=='a')pass[i]='2';
else if(pass[i]=='b')pass[i]='2';
else if(pass[i]=='c')pass[i]='2';
else if(pass[i]=='d')pass[i]='3';
else if(pass[i]=='e')pass[i]='3';
else if(pass[i]=='f')pass[i]='3';
else if(pass[i]=='g')pass[i]='4';
else if(pass[i]=='h')pass[i]='4';
else if(pass[i]=='i')pass[i]='4';
else if(pass[i]=='j')pass[i]='5';
else if(pass[i]=='k')pass[i]='5';
else if(pass[i]=='l')pass[i]='5';
else if(pass[i]=='m')pass[i]='6';
else if(pass[i]=='n')pass[i]='6';
else if(pass[i]=='o')pass[i]='6';
else if(pass[i]=='p')pass[i]='7';
else if(pass[i]=='q')pass[i]='7';
else if(pass[i]=='r')pass[i]='7';
else if(pass[i]=='s')pass[i]='7';
else if(pass[i]=='t')pass[i]='8';
else if(pass[i]=='u')pass[i]='8';
else if(pass[i]=='v')pass[i]='8';
else if(pass[i]=='w')pass[i]='9';
else if(pass[i]=='x')pass[i]='9';
else if(pass[i]=='y')pass[i]='9';
else if(pass[i]=='z')pass[i]='9';
}
printf("%s\n",pass);
return 0;
}
复杂度分析
时间复杂度: 我们读入和遍历每一位转换,每个具体的位上的转换是常数时间,所以总时间复杂度为O(n)
空间复杂度: 我们用一个字符串数组,记录读入和最终的转换结果,所以总空间复杂度为O(n)
利用ASCII的性质和char的运算
通过查ASCII表,或者已有的ASCII知识,我们可以知道字符'0''9','a''z','A'~'Z'分别是连续的
另外,在c++里,char可以直接当做数值计算,而它的值就是ascii的值。因此你不需要去记住任何ascii的值是多少,而可以直接用char的字符参与运算
所以对于上面3种情况分别处理
- 数字,不变
- 小写字母,我们通过建立映射表,和基于ascii连续,分别映射到对应数字字符
- 大写字母,我们通过
字符-'A' + 1 + 'a'
得到小写字母右移, 这里要循环右移,需要注意取模运算。
代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i = (a) ;i<(b);i++)
int main(){
char ch[30];
// 利用字符在ascii中的连续性
rep(c,'a','c'+1)ch[c-'a'] = '2';
rep(c,'d','f'+1)ch[c-'a'] = '3';
rep(c,'g','i'+1)ch[c-'a'] = '4';
rep(c,'j','l'+1)ch[c-'a'] = '5';
rep(c,'m','o'+1)ch[c-'a'] = '6';
rep(c,'p','s'+1)ch[c-'a'] = '7';
rep(c,'t','v'+1)ch[c-'a'] = '8';
rep(c,'w','z'+1)ch[c-'a'] = '9';
char pass[110];
scanf("%s",pass);
int n = strlen(pass);
rep(i,0,n){
if('0' <= pass[i] && pass[i] <= '9'){ // 利用char可以直接比较 和ascci中值的连续性
continue;
}else if('A' <= pass[i] && pass[i] <= 'Z'){ // 利用char可以直接比较 和ascci中值的连续性
pass[i] = (pass[i]-'A'+1)%26+'a';
}else{
pass[i] = ch[pass[i] - 'a']; // 利用char可以直接比较 和ascci中值的连续性
}
}
printf("%s\n",pass);
return 0;
}
复杂度分析
时间复杂度: 我们读入和遍历每一位转换,每个具体的位上的转换也是常数时间,所以总时间复杂度为O(n)
空间复杂度: 我们用了一个转换表数组和字符串长度无关的常数大小,一个字符串数组记录读入和最终的转换结果,所以总空间复杂度为O(n)