2016-12-29 202 views
3

我預期這是直截了當使用用於與replace(str.begin(), str.end(), "x", "y")循環而是"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串ALPH由三個旋轉。

輸出凱撒給出預期結果。 (abcdef ...變成xyzabc ...只是在打印凱撒時)

我的循環似乎是把它搞亂了,當給出hello它產生ccaaa。我測試了替換一個字母,它的工作原理,但似乎我的for循環是什麼問題,但我似乎無法找出什麼是錯的。

UPDATE:

我發現了一個辦法做到這一點,它支持使用while循環來檢查,如果它是按字母順序排列,然後通過拼音每個字母一個字母串的比較,直到他們進入非字母字符匹配,並用旋轉的凱撒字母替換它,如果它們不匹配則進入下一個,當發現它將'j'重置爲0時,這樣它可以再次爲下一個字母按增量'i'這次做,如果char不是一個字母,它只會將'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; 
} 
+1

*我驗證了它的效果。* - 這與我們需要的 - [mcve]相反。另外:'char caesar [arraySize];'這是無效的C++語法。數組必須有編譯時間界限,而不是可變的。將'arraySize'更改爲'const int arraySize = ...';爲什麼不只是使用'std :: rotate'而不是'leftRotate'函數,以便我們確信「它有效」? – PaulMcKenzie

+3

逐步循環。假設你用'h'代替'e'。你的字符串變成'hhllo'。但是,然後你用'k'代替所有的'h',你得到'kkllo'等等。你需要確保一個字母只被替換一次。 –

+0

@JohnnyMopp哦,是的,很明顯,非常感謝,但我會如何去做這件事? – Lamb

回答

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

注:它使用的字符代碼來獲取指標,所以它必須改變,以處理任何事情除「abc ... xyz」外。

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; 
} 
相關問題