题解 | #字符串加解密#
字符串加解密
http://www.nowcoder.com/practice/2aa32b378a024755a3f251e75cbf233a
题目的主要信息:
- 对输入的字符串进行加解密,英文字母用该英文字母的后一个字母替换,同时字母变换大小写;数字则把该数字加1。其他字符不做变化。
- 解密方法为加密的逆过程。
方法一:
构造加密encoder和解密decoder两个函数。加密和解密的思路很像,这里主要讲讲加密的过程,解密类似。遍历一遍字符串,若当前字符是英文字母,判断是大写还是小写,通过ASCII码的相对位置转换大小写,再将ASCII码加一,变为后一位字母;若当前字符是数字,则直接将ASCII码加一。需要注意的是,z、Z和0是边界情况,需要单独判断处理。
具体做法:
#include<iostream>
#include<string>
using namespace std;
void encoder(string str)
{
for(int i=0;i<str.size();i++)
{
if(isalpha(str[i])){//英文字母
if(str[i]>='a'&&str[i]<='z'){//小写字母
if(str[i]=='z'){
str[i]='A';
}else{
str[i]=str[i]-'a'+'A'+1;//变换大小写同时用后一个字母替换
}
}else{//大写字母
if(str[i]=='Z'){
str[i]='a';
}else{
str[i]=str[i]-'A'+'a'+1;//变换大小写同时用后一个字母替换
}
}
}else{//数字
if(str[i]<'9') str[i]++;
else str[i]='0';//9变为0
}
}
cout<<str<<endl;
}
void decoder(string str)
{
for(int i=0;i<str.size();i++)
{
if(isalpha(str[i])){//英文字母
if(str[i]>='a'&&str[i]<='z'){//小写字母
if(str[i]=='a'){
str[i]='Z';
}else{
str[i]=str[i]-'a'+'A'-1;//变换大小写同时用前一个字母替换
}
}else{//大写字母
if(str[i]=='A'){
str[i]='z';
}else{
str[i]=str[i]-'A'+'a'-1;//变换大小写同时用前一个字母替换
}
}
}else{//数字
if(str[i]>'0') str[i]--;
else str[i]='9';//0变为9
}
}
cout<<str<<endl;
}
int main()
{
string str1, str2;
while(cin>>str1>>str2)
{
encoder(str1);
decoder(str2);
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串进行加密解密。
- 空间复杂度:,只用了常数空间。
方法二:
方法二采用查表法。首先建立list1和list2分别存储加密前和加密后的字符,list1和list2一一对应,例如,list1[i]的字符经过加密后是list2[i],list2[j]经过解密后是list1[j]。因此我们只需要遍历一遍字符串,找到他们在list1中的位置,对应的list2相同位置的字符即为加密后的字符。
具体做法:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
string strlist1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";//加密前的字符list
string strlist2 = "BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza1234567890";//加密后的字符list,和list1一一对应
void encoder(string str)
{
for(int i=0; i<str.size(); i++)//遍历一遍字符串
{
for(int j=0; j<strlist1.size(); j++)//找到在list1中的位置
{
if(str[i] == strlist1[j])
{
str[i] = strlist2[j];//加密
break;
}
}
}
cout<<str<<endl;
}
void decoder(string str)
{
for(int i=0; i<str.size(); i++)//遍历一遍字符串
{
for(int j=0; j<strlist2.size(); j++)//找到在list2中的位置
{
if(str[i] == strlist2[j])
{
str[i] = strlist1[j];//解密
break;
}
}
}
cout<<str<<endl;
}
int main()
{
string str1, str2;
while(cin>>str1>>str2)
{
encoder(str1);//加密
decoder(str2);//解密
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串进行加密解密。
- 空间复杂度:,虽然使用了strlist,但是只使用了常数大小空间。