题目的主要信息:

  • 将输入的改动后的密文转换为原始的密文。
  • 加密的规则是 1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0数字和其他的符号都不做变换。
  • 大写字母变成小写字母之后再往后移一位。

方法一:

查表法。首先建立dict1和dict2分别存储加密后和加密前的字符,dict1和dict2一一对应,例如,dict1[i]的字符经过解密后是dict2[i]。因此我们只需要遍历一遍字符串,找到他们在dict1中的位置,用对应的dict2相同位置的字符替换当前字符即为原始的字符。

alt

具体做法:

#include<iostream>
#include<string>
using namespace std;
const string dict1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";//解密前
const string dict2="bcdefghijklmnopqrstuvwxyza22233344455566677778889999";//解密后
 


int main(){
    string str;
    while(getline(cin,str)){//逐行输入
        for(int i=0;i<str.size();i++){//遍历一遍字符串
            for(int j=0;j<dict1.size();j++){//在dict1中找到对应的位置
                if(dict1[j]==str[i]){//替换为dict2中的相同位置的字符
                    str[i]=dict2[j];
                    break;
                }
            }
        }
        cout<<str<<endl;
    }
    return 0;
}


复杂度分析:

  • 时间复杂度:O(n)O(n),第一个for循环遍历一遍字符串,第二个for循环是常数级的。
  • 空间复杂度:O(1)O(1),dict1和dict2的大小是固定的常数大小。

方法二:

遍历一遍字符串,若当前字符是英文字母,判断是大写还是小写,如果是大写字母,加上33即为后一位的小写字母;若当前字符是小写字母,根据abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9的规则逐个判断转换。

具体做法:

#include<iostream>

using namespace std;

int main(){
    string str;
    while(cin>>str){
        for(int i=0;i<str.size();i++){
            if(str[i]>='A' && str[i]<'Z'){//大写字母变成小写字母后移一位
                str[i] = str[i] + 33;
            }
            else if(str[i] == 'Z'){
                str[i] = 'a';
            }else if(str[i]>='a' && str[i]<='c'){//abc--2
                str[i] = '2';
            }else if(str[i]>='d' && str[i]<='f'){//def--3
                str[i] = '3';
            }else if(str[i]>='g' && str[i]<='i'){//ghi--4
                str[i] = '4';
            }else if(str[i]>='j' && str[i]<='l'){//jkl--5
                str[i] = '5';
            }else if(str[i]>='m' && str[i]<='o'){//mno--6
                str[i] = '6';
            }else if(str[i]>='p' && str[i]<='s'){//pqrs--7
                str[i] = '7';
            }else if(str[i]>='t' && str[i]<='v'){//tuv--8
                str[i] = '8';
            }else if(str[i]>='w' && str[i]<='z'){//wxyz--9
                str[i] = '9';
            }
        }
        cout<<str<<endl;
        return 0;
    }
}


复杂度分析:

  • 时间复杂度:O(n)O(n),第一个for循环遍历一遍字符串,逐个判断。
  • 空间复杂度:O(1)O(1),只用了常数空间。