题目的主要信息:
- 输入两串字符,第一个单词作为密匙,去除单词中的重复字符,再用字母表中剩余的字母填充完整。
- 在对字符串进行加密时,用密钥中的字母一一取代原文的字母,需要保留字母的大小写状态。
方法一:
我们可以根据题意进行计算求解。用一个vector保存密钥,对遍历一遍输入的单词,将所有字母转换为小写字母,不保留重复的字符,然后在vector中加入26个字母中剩余的其他字母,这样就完成了密钥。需要注意的是,上面获得的密钥全部是小写字母。对字符串加密的时候,判断当前字母s[i]是大写还是小写,如果是小写字母,则直接通过ASCII码计算相对位置s[i]-'a',获得密钥中对应的字母;如果是大写字母,得到密钥中对应的字母后再转为大写字母。
具体做法:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
string s1,s2;
while(cin>>s1>>s2){//可能有多个输入
vector<char> key;//密钥
for(int i=0;i<s1.size();i++){
if(s1[i]>='A'&&s1[i]<='Z'){//统一字母大小写
s1[i]=s1[i]-'A'+'a';
}
auto iter=find(key.begin(),key.end(),s1[i]);
if(iter==key.end()){//去除单词中的重复部分,存到密钥中
key.push_back(s1[i]);
}
}
for(char c='a';c<='z';c++){//将剩余的字母存到密钥中
auto iter=find(key.begin(),key.end(),c);
if(iter==key.end()){
key.push_back(c);
}
}
char result;
//接下来对字符串进行加密
for(int i=0;i<s2.size();i++){
if(s2[i]>='a'&&s2[i]<='z'){//原字符是小写的
result=key[s2[i]-'a'];
}
if(s2[i]>='A'&&s2[i]<='Z'){//原字符是大写的
result=key[s2[i]-'a']-'a'+'A';//根据ASCII码转换为大写
}
cout<<result;
}
cout<<endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:O(n),需要遍历一遍字符串。
- 空间复杂度:O(1),虽然使用了vector保存密钥,但是vector大小为26个字符,是常数空间大小。
方法二:
方法一是使用了find函数查找重复字母,我们也可以用一个数组count来统计每个字母出现的频数,这个方法不会增加算法的复杂度。遍历单词时,增加当前字母的频数,只有当频数为1时,说明该单词是首次出现的,需要存到密钥中。补充26个字母中剩余字母时,只要将那些频数为0的字母加入密钥。
具体做法:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
string s1,s2;
while(cin>>s1>>s2){//可能有多个输入
vector<char> key;//密钥
int count[26]={0};//统计字母出现的次数
for(int i=0;i<s1.size();i++){
if(s1[i]>='A'&&s1[i]<='Z'){//统一字母大小写
s1[i]=s1[i]-'A'+'a';
}
int p=s1[i]-'a';
count[p]++;//计算字母出现的频数
if(count[p]==1){//该字母第一次出现,把它加到密钥中
key.push_back(s1[i]);
}
}
for(char c='a';c<='z';c++){//将剩余的字母存到密钥中
int p=c-'a';
if(count[p]==0){//该字母没有出现过,把它加到密钥中
key.push_back(c);
}
}
char result;
//接下来对字符串进行加密
for(int i=0;i<s2.size();i++){
if(s2[i]>='a'&&s2[i]<='z'){//原字符是小写的
result=key[s2[i]-'a'];
}
if(s2[i]>='A'&&s2[i]<='Z'){//原字符是大写的
result=key[s2[i]-'a']-'a'+'A';//根据ASCII码转换为大写
}
cout<<result;
}
cout<<endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:O(n),需要遍历一遍字符串。
- 空间复杂度:O(1),虽然使用了vector保存密钥,和count数组统计字母出现的频数,但是vector和count大小为26个字符,是常数空间大小。