0

文字列を操作できるように大文字に変換しようとしていますが、自然な大文字の文字列を正常に操作でき、小文字を大文字に変換することもできますが、この変換方法を使用すると操作できません。

たとえば、暗号化で「hello」を渡すと、暗号化された文字列は「HELLO」になりますが、「HELLO」を (自然に大文字で) 渡すと、正しくシフトします。

使用する必要がある大文字を強制する別の方法はありますか、それとも何か間違っていますか?

int Caesar::encrypt (const std::string &message, std::string &emessage) {
  int count = 0;
  emessage = message;
  std::transform(emessage.begin(), emessage.end(), emessage.begin(), ::toupper);
  for (std::string::size_type i = 0; i < message.size(); i++) {
    for (int j = 0; j < 26; j++) {
      if (emessage[i] == std_alphabet[j]) {
        std::replace(emessage.begin(), emessage.end(), message[i], c_alphabet[j]);
      }
    }
    count++;
  }
  return count;
}

コンストラクタ:

Caesar::Caesar (int shift) {
    // loop to populate vector with 26 letters of English alphabet
    // using ASCII uppcase letter codes
  for (int i = 0; i < 26; i++) {
    std_alphabet.push_back(i + 65);
  }
    // fills Caesar alphabet with standard generated alphabet
  c_alphabet = std_alphabet;
    // shifts Caesar alphabet based off the constructor parameter
  std::rotate(c_alphabet.begin(), c_alphabet.begin() + shift, c_alphabet.end());
}

テストファイル:

void testCaesar() {
  Caesar test(4);
  std::string original = "HELLO";
  std::string encrypted = "";
  test.encrypt(original,encrypted);
  std::cout << encrypted << std::endl;
  std::cout << original << std::endl;
}

int main() {
  testCaesar();
  return 0;
}

明らかにヘッダーとインクルードなどがありますが、それは基本的なコードです

ヘッダー ファイルには 2 つのプライベート ベクトルが含まれます

4

1 に答える 1

2

あなたが見ている特定の問題は、ここで間違ったものを置き換えていることです:

std::replace(emessage.begin(), emessage.end(), message[i], c_alphabet[j]);

messageが小文字の場合、emessageすべて大文字になり、いずれもmessage[i]. 交換しても何も起こらないように。あなたが意味したのは:

std::replace(emessage.begin(), emessage.end(), emessage[i], c_alphabet[j]);
                                               ^^^^^^^^^^^

HELLOそうは言っても、あなたのアルゴリズムは、シフト 4 の暗号化として完全に間違っていますBCBBA。文字には 1 対 1 のマッピングがあるためH、 とLの両方がB. やりたいことは、次の文字に置き換えるだけで、各文字をシフトすることです。あれは:

for (std::string::size_type i = 0; i < emessage.size(); ++i) {
    emessage[i] = c_alphabet[emessage[i] - 'A'];
}

実際には最初の変換ステップは必要ありません。

emessage = message;
for (std::string::size_type i = 0; i < emessage.size(); ++i) {
    emessage[i] = c_alphabet[::toupper(emessage[i]) - 'A'];
}

countあなたの(これはちょうどサイズなので、冗長です)をドロップし、メッセージを値で受け取るだけで、全体をかなり簡略化できます。

std::string encrypt(std::string from) { // intentionally copying
    for (char& c : from) {
        c = c_alphabet[::toupper(c) - 'A'];
    }
    return from;
}
于 2015-09-03T18:23:01.523 に答える