我希望使用带有replace(str.begin(), str.end(), "x", "y")
的for循环直截了当,而"x"
和"y"
是数组中的某个字符,因此:replace(str.begin(), str.end(), arrX[1], arrY[1])
在循环中:
for (int i = 0; i < arraySize; i++) {
replace( str.begin(), str.end(), arrX[i], arrY[i]);
}
但在我的代码中:
#include <iostream>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
string Caesar(string str) {
char alph[] = {'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'};
string caesar = "abcdefghijklmnopqrstuvwxyz";
const int arraySize=sizeof(alph)/sizeof(alph[0]);
rotate(caesar.begin(), caesar.begin()+3, caesar.end());
for (int i = 0; i < arraySize; i++) {
replace(str.begin(), str.end(), alph[i], caesar[i]);
}
return str;
}
int main() {
cout << Caesar("hello");
}
caeser string alph旋转三次。
输出凯撒可以得到预期的结果。 (abcdef ...变成xyzabc ......只是打印凯撒。)
我的循环似乎弄乱了它,当给出hello
它产生ccaaa
时。我测试了替换一个字母并且它有效但看起来我的循环问题是什么,但我似乎无法找出问题所在。
更新:
我找到了一种方法来支持非字母字符,使用while循环检查它是否是按字母顺序排列,然后通过字母表将每个字母与字符串中的字母进行比较,直到它们匹配,然后将其替换为旋转凯撒字母,如果它们不匹配则转到下一个字母,当发现它将'j'重置为0时,如果字符不是a,它可以通过增加'i'再次为下一个字母再次执行字母它只是将'i'增加到下一个字符,只是跳过它直到它到达新字母或字符串的结尾。
#include <iostream>
#include <algorithm>
using namespace std;
bool IsInArray(string array, char element) {
for(int i = 0; i < array.length(); i++){
if(array[i] == element){
break;
}
}
}
string rot(int n, string str) {
transform(str.begin(), str.end(), str.begin(), ::tolower);
string alph = "abcdefghijklmnopqrstuvwxyz";
string ciph = alph;
rotate(ciph.begin(), ciph.begin() + n, ciph.end());
int i = 0;
int j = 0;
while (i < str.length()) {
if (IsInArray(alph, str[i])) {
if (str[i] == alph[j]) {
str[i] = ciph[j];
i++;
j = 0;
}
else {
j++;
}
}
else {
i++;
}
}
return str;
}
int main() {
cout << rot(2, "This cipher works with more than just alpha chars!");
return 0;
}
答案 0 :(得分:1)
这是使用标准函数和lambda函数执行此操作的一种方法:
string Caesar(std::string str) {
std::string caesar = "abcdefghijklmnopqrstuvwxyz";
std::rotate(caesar.begin(), caesar.end()-3, caesar.end());
std::transform(str.begin(), str.end(), str.begin(),
[caesar](char c) -> char { return caesar[c - 'a']; });
return str;
}
注意:它使用char代码来获取索引,因此必须更改它以处理除“abc ... xyz”之外的任何内容。
答案 1 :(得分:1)
作为优化:如果您只使用小写字母a-z
,则可以在不使用两个数组且不使用函数leftRotatebyOne
的情况下执行此操作。而是使用ASCII值。
std::string Caesar(std::string str){
int delta = 'z' - 'a' + 1;
int rotateBy = 3;
for(int i = 0; i < str.length(); i++){
char c = str[i] - rotateBy;
if(c < 'a')
c += delta;
str[i] = c;
}
return str;
}