将字符从一个数组替换为另一个数组到字符串

时间:2016-12-29 21:54:33

标签: c++ arrays string replace

我希望使用带有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;
}

2 个答案:

答案 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;
}