任务:此密码将每个字母移动多个字母。如果移位使您越过字母表的末尾,只需旋转回到字母表的前面即可。
例如: string = "ABC Def Ghi 999 -*%/&()[]" shift(你输入的数字) = 1(可以是任意整数)
程序应该这样打印:Bcd Efg Hij -*%/&()[]
我用 void 函数做了这个,但是一旦我尝试用字符串函数做同样的事情,它就不起作用了。它只是处理字符串的第一个元素然后返回值。对于这种特殊情况 我的程序打印出来像“Bbc Def Ghi 999 -*%/&()[]”
有什么办法可以解决这个问题吗?
#include <iostream>
#include <cmath>
using namespace std;
string Cipher(string password, int shift) {
char Uppercase[26] = { 'A','B','C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O','P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y','Z' };
char Lowercase[26] = { 'a','b','c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o','p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y','z' };
for (int i = 0; i < password.length(); i++) {
for (int k = 0; k < 26; k++) {
int add = shift + k;
if (password[i] == Uppercase[k]) {
for (int i = 0; add > 25; i++) { // controlling add isn't bigger than 25
add -= 25;
}
password[i] = Uppercase[add]; // converting each letter
}
else if (password[i] == Lowercase[k]) {
for (int i = 0; add > 25; i++) { // controlling add isn't bigger than 25
add -= 25;
}
password[i] = Lowercase[add]; //converting each letter
}
else {
k = 25; // if element of string is different from letters, program goes to next element
}
}
}
return password;
}
int main() {
cout << "Please enter an integer different from 0 and multiples of 25: ";
string password = "Abc def ghi 999 -*%/&()[]";
int shift;
cin >> shift;
cout<< Cipher(password, shift);
system("pause>0");
}
答案 0 :(得分:1)
您的加密问题可以通过使用现代 C++ 的一个语句来解决。
但是因为这个有点高级,所以我会给出详细的解释。
让我们先想想,做什么,然后如何实施。
什么:
方法:
我们将首先使用 isalpha 函数检查原始字母是否为字母。
因此,对于字母的情况,我们将检查该字母是大写还是小写。实际上,我们只检查是否是大写字母。
因为如果不是,那么它一定是小写字母(因为它肯定是一个字母,我们之前做过检查,如果不是大写,那么它就是小写)。对于此检查,我们使用 isupper 函数。
然后我们将执行轮班操作。并转换回字母,考虑到情况。
我们假设是 ASCII。如果我们要将 ASCII 字母/字符转换为基于 0 的索引,我们需要执行以下操作:
如果我们查看 ASCII 表,那么我们会看到,'A' 等于 65,依此类推。因此,为了获得从 0 开始的索引,我们从字母中减去 65。然后我们有一个介于 0 和 25 之间的索引值。
然后我们添加移位值。当然可能有溢出。但是,这可以通过模 26 除法简单地纠正。
所以:26->0、27->1、28->2 等等。相当简单。但是,因为我们想稍后再有一个字母,所以我们将在这个结果上加 65。
对于小写字母,我们将执行几乎相同的操作,但使用 97 作为字母 'a' 的偏移量。
然后,我们可以通过使用三元或 conditional 运算符将所有东西放在一个表达式中。
std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c
这是一个简短的
// Check if letter/character is alpha
if (std::isalpha(c)) {
// Now check for upper or lower case
if (std::isupper(c)) {
// The character is uppercase
c = (c - 65 + shift) % 26 + 65;
}
else {
// The character is lower case
c = (c - 97 + shift) % 26 + 97;
}
}
else {
// The character is not alpha
}
和单衬一样,没有区别
所以,首先,检查 alpha。如果为真,则检查大写,如果为真,则对大写字母进行转换,否则对小写字母进行转换。如果不是字母,则保持不变。
然后,我们将所有这些作为 Lambda 表达式嵌入到 std::transform
语句中。请参阅 here 了解说明。
整个转换过程的结果将只有一个语句:
std::transform(password.begin(), password.end(), password.begin(), [shift](const char c)
{return std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c; });
最后,我们构建了一个用于演示目的的小型驱动程序:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Our password
std::string password = "Abc def ghi 999 -*%/&()[]";
// Give instruction to the user
std::cout << "\nPlease enter a postive integer: ";
// Get number of shifts from user and check, if the value could be read
if (int shift{}; std::cin >> shift && shift > 0) {
// Now do the encryption
std::transform(password.begin(), password.end(), password.begin(), [shift](const char c)
{return std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c; });
// Show the result to the user
std::cout << "\n\nEncrypted passphrase: \t" << password << '\n';
}
else std::cerr << "\n\n*** Error: Problem with input!\n\n";
return 0;
}
而且,由于单行代码可能太高级了,让我们使用明确且更冗长的代码。只是为了完成:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Our password
std::string password = "Abc def ghi 999 -*%/&()[]";
// Give instruction to the user
std::cout << "\nPlease enter a postive integer: ";
// Get number of shifts from user and check, if the value could be read
if (int shift{}; std::cin >> shift && shift > 0) {
// --------------Can be written in one statement -----------------------
for (char& c : password) {
// Check if letter/character is alpha
if (std::isalpha(c)) {
// Now check for upper or lower case
if (std::isupper(c)) {
// The character is uppercase
c = (c - 65 + shift) % 26 + 65;
}
else {
// The character is lower case
c = (c - 97 + shift) % 26 + 97;
}
}
else {
// The character is not alpha
}
// ------------------------------------------------------------------
}
// Show the result to the user
std::cout << "\n\nEncrypted passphrase: \t" << password << '\n';
}
else std::cerr << "\n\n*** Error: Problem with input!\n\n";
return 0;
}
答案 1 :(得分:0)
在 k 循环中,您确定字母在字母表中的索引。但是,当例如i=1
然后 password[1]
代表字母“b”。现在,从 k==0
开始 k 循环,其中 Uppercase[0]
和 Lowercase[0]
分别代表 'A' 和 'a',您直接以 else
条件结束,您的k-loop 不做任何事情就终止(你设置 k=25
并增加它)。这是一个固定版本(请注意,我还使用模运算符 %
来确保 0 < add < 26
:
#include <iostream>
#include <cmath>
using namespace std;
string Cipher(string password, int shift) {
char Uppercase[26] = { 'A','B','C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O','P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y','Z' };
char Lowercase[26] = { 'a','b','c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o','p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y','z' };
for (int i = 0; i < password.length(); i++) {
for (int k = 0; k < 26; k++) {
int add = (shift + k)%26;
if (password[i] == Uppercase[k]) {
password[i] = Uppercase[add]; // converting each letter
break;
}
else if (password[i] == Lowercase[k]) {
password[i] = Lowercase[add]; //converting each letter
break;
}
}
}
return password;
}
int main() {
cout << "Please enter an integer different from 0 and multiples of 25: ";
string password = "Abc def ghi 999 -*%/&()[]";
int shift;
cin >> shift;
cout<< Cipher(password, shift);
system("pause>0");
}