题解 | #字符串加解密#

字符串加解密

http://www.nowcoder.com/practice/2aa32b378a024755a3f251e75cbf233a

题目的主要信息:

  • 对输入的字符串进行加解密,英文字母用该英文字母的后一个字母替换,同时字母变换大小写;数字则把该数字加1。其他字符不做变化。
  • 解密方法为加密的逆过程。

方法一:

构造加密encoder和解密decoder两个函数。加密和解密的思路很像,这里主要讲讲加密的过程,解密类似。遍历一遍字符串,若当前字符是英文字母,判断是大写还是小写,通过ASCII码的相对位置转换大小写,再将ASCII码加一,变为后一位字母;若当前字符是数字,则直接将ASCII码加一。需要注意的是,z、Z和0是边界情况,需要单独判断处理。 alt

具体做法:

#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;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),需要遍历一遍字符串进行加密解密。
  • 空间复杂度:O(1)O(1),只用了常数空间。

方法二:

方法二采用查表法。首先建立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;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),需要遍历一遍字符串进行加密解密。
  • 空间复杂度:O(1)O(1),虽然使用了strlist,但是只使用了常数大小空间。
全部评论

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
评论
12
收藏
分享
牛客网
牛客企业服务