题意

给定一个只包含数字和大小写字母的字符串,和一个映射规则,求映射后的字符串。

其中映射规则为:

  1. 数字不转换
  2. 小写字母按照手机九宫格键盘上转换成数字
  3. 大写字母转换成小写字母的循环右移一位

限制:字符串长度不大于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)O(n)

空间复杂度: 我们用一个字符串数组,记录读入和最终的转换结果,所以总空间复杂度为O(n)O(n)O(n)

利用ASCII的性质和char的运算

通过查ASCII表,或者已有的ASCII知识,我们可以知道字符'0''9','a''z','A'~'Z'分别是连续的

alt

alt

alt

另外,在c++里,char可以直接当做数值计算,而它的值就是ascii的值。因此你不需要去记住任何ascii的值是多少,而可以直接用char的字符参与运算

所以对于上面3种情况分别处理

  1. 数字,不变
  2. 小写字母,我们通过建立映射表,和基于ascii连续,分别映射到对应数字字符
  3. 大写字母,我们通过 字符-'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)O(n)

空间复杂度: 我们用了一个转换表数组和字符串长度无关的常数大小,一个字符串数组记录读入和最终的转换结果,所以总空间复杂度为O(n)O(n)O(n)