我正在编写一个初学者程序,首先输入一个整数 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;
}
答案 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;
}