将一个字符串中的字符替换为C ++中另一字符串中的字符

时间:2019-12-28 05:47:57

标签: c++

我正在为我的C ++项目制作一个密码程序。我的方法是声明和初始化两个字符串,第一个为alphabet,另一个为key,如下所示。

string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};

我想在密码中将所有这52个字母互相配对。也就是说,将小a替换为大写Z,将小b替换为Y,依此类推。

将提示用户输入一个字符串,该字符串将存储在input中。我的想法是循环遍历input字符串并将其与alphabet匹配,从而在key字符串中找到其对。这很容易,因为两对将具有相同的索引。但是,如何交换它们?我可以在swap(input[i], key[i])中使用循环,但这只会使每个字符串成为ZYXW...,因此我无法在此处编写逻辑...下面是到目前为止的全部代码。

#include <iostream>
#include <string>

using namespace std;

   int main()
{

       string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
       string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};
       int choice {};

       cout<<"Welcome to the Cypher Program";
       cout<<"\nYou can encode and decode your messages to make sure they remain secret!";
       cout<<"\nWould you like to encode(Press 1) or decode(Press 2) a message?"<<endl;

       cin>>choice;
       //Encoding
       if (choice == 1)
       {
           string input {};
           cout<<"Enter a string to encrypt"<<endl;
           getline(cin.ignore(), input);  //testString

           cout<<"Your encrypted message is: "<<endl;
           for(int i {0}; i<input.length(); i++){
               swap(input[i], key[i]);
           }
           cout<<input;                  //ZYXWVUTSRQ
       }


       return 0;

}

我真正想做的是:

  • 从用户那里获取输入
  • 对于输入的每个字母,在alphabet中找到其索引
  • 使用该索引,将字符替换为key
  • 将新字符串显示回给用户。

3 个答案:

答案 0 :(得分:1)

步骤1:在原始字符串中查找字符的索引

if (input[i] >= 97)
{
    index = input[i]-97; 

}
else
{
    index = (input[i]-65) + 26; 
}

现在使用

input[i] = key[index];

答案 1 :(得分:1)

我将在这里讨论两种简单的方法。

  1. 首先要按照您的建议进行操作,从alhphabet中找到字母的索引,然后使用该索引从key中找到编码的字母。

  2. p>
  3. 在这里,您可以通过观察编码中的模式来使用一个简单的技巧。只要是大写字母,就可以从其ASCII值减去'A'以获得offset,然后从ASCII值z减去该偏移量即可得到编码字母。当它是小写字母时,您会注意到类似的模式。

下面是这两种方法的示例代码。

#include <iostream>
#include <string>
using namespace std;
int main(){
    string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};
    string input1 {"testString"}, input2 {"testString"};
    cout<<"Your encrypted message is (Approach 1) : "<<endl;
    // Approach 1
    for(int i {0}; i<input1.length(); i++){
        int idx;
        for(idx=0;idx<alphabet.length();idx++) // find index from alphabet
            if(input1[i]==alphabet[idx])
                break;
        input1[i] = key[idx]; // replace with key
    }
    cout<<input1<<endl; //GVHGhGIRMT
    // Approach 2
    cout<<"Your encrypted message is (Approach 2) : "<<endl;
    for(int i {0}; i<input2.length(); i++){
        if(input2[i] >= 'A' && input2[i]<='Z')
            input2[i] = 'z' - (input2[i]-'A');
        else if(input2[i] >= 'a' && input2[i]<='z')
            input2[i] = 'A' + ('z'-input2[i]);
    }
    cout<<input2; //GVHGhGIRMT
    return 0;
}

输出

Your encrypted message is (Approach 1) : 
GVHGhGIRMT
Your encrypted message is (Approach 2) : 
GVHGhGIRMT

答案 2 :(得分:1)

嗯,您的原始代码还不错。您只需要用分配替换掉交换。这使您的原始数据保持不变。

input[i] = key[alphabet.find(input[i])];

您应该在{alphabet“和” key“之前添加const,否则编译器将阻止您的代码。

顺便说一句,使用此对称密钥,编码和解码是相同的。

不确定为什么要写getline(cin.ignore(), input);而不是getline(cin, input);。那应该纠正。

计算方法的优点是密钥字符串将不在exe文件中。 您也可以使用XOR 255(result += input[i] ^255(它会翻转所有位)或256-input [i];

使用std::transform算法的“更现代”的C ++解决方案下面

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    // The encoding alphabet and key
    constexpr std::string_view alphabet{ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ _" };
    constexpr std::string_view  key{ "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba_ " };    

    // String to encrypt
    std::string message{"Hello world"};

    // Here we will store the result
    std::string result;

    std::transform(message.begin(), message.end(), std::back_inserter(result), [&key, &alphabet](const char c)
        { size_t pos{ alphabet.find(c) }; return (pos != std::string::npos) ? key[pos] : '_'; });

    // Show result
    std::cout << "\nEncrypted: " << result << "\n";

    message = result;
    result.clear();
    std::transform(message.begin(), message.end(), std::back_inserter(result), [&key, &alphabet](const char c)
        { size_t pos{ alphabet.find(c) }; return (pos != std::string::npos) ? key[pos] : '_'; });

    // Show result
    std::cout << "\nDecrypted: " << result << "\n";

    return 0;
}