如何以最佳方式包裹字母位置移位?

时间:2018-04-08 08:25:37

标签: c++ encoding

我正在编写一个初学者程序,首先输入一个整数 n 然后输入一个单词(全部大写),并将每个字母移动到字母表中的 n 位置。我有向下移动的部分(见下面的代码),但我正在努力将其包裹起来,所以它一旦超过Z就开始于字母表的开头。有什么建议吗?

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main()
{
int n;
cin >> n;
string output = "";
string str;
cin >> str;
    for (char c : str) {
        c = c + n; 
        output = output + c;
    }
cout << output << endl;

return 0;
}

3 个答案:

答案 0 :(得分:1)

可能最容易理解:

将输入字符移动到[0,25]

范围内
(c - A_idx)

添加偏移量

(c - A_idx) + n

获取偏移的模数(包裹它)

(c - A_idx) + n) % Letters

将其映射回ascii

预期的范围
((c - A_idx) + n) % Letters + A_idx

完整代码

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main()
{
    int n;
    cin >> n;
    string output = "";
    string str;
    cin >> str;
    const auto A_idx = 65;
    const auto Z_idx = 90;
    const auto Letters = Z_idx - A_idx + 1;// 26 maybe?
    for (char c : str) {
        c = ((c - A_idx) + n) % Letters + A_idx;
        output = output + c;
    }
    cout << output << endl;

    return 0;
}

答案 1 :(得分:1)

有多种方法可以实现这一点,所以这一切都归结为最具可读性的方法。就个人而言,我有这样的事情:

int n;
std::cin >> n;
std::string word = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (auto& c : word)
{
    c += n;
    if (c > 'Z')
        c -= 26;
}
std::cout << word;

它只是递增c,如果c大于'Z',它会减少字母表中的字母数量(这对任何人都应该是显而易见的)。

您也可以预先检查是否要超过'Z',如果是这样的话,请改为使用以下内容:

if (c + n> 'Z')
    c += (n - 26);
else
    c += n;

答案 2 :(得分:0)

有无数种方法可以做到这一点,因此,这样的问题通常会被关闭。没有正确的答案,建议只是继续下去。修复版本的最快方法是在循环的每次迭代中添加一个环绕检查。它几乎是最佳的,特别是因为你只做了一个字符串。但优化在这里很愚蠢。计算将比读取字符串快几百万或几十亿倍。

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main()
{
    int n;
    cin >> n;
    string str;
    cin >> str;
    string output;
    for (char c : str) {
        c = c + n; 
        if (c > 'Z') c -= 26;  // One added line.
        output = output + c;
    }
    cout << output << '\n';
    return 0;
}