C++ で文字列が回文かどうかをチェックする

胡金庫 2023年10月12日
  1. C++ で文字列の回文をチェックするには rbegin/rend メソッドを用いて string のコピーコンストラクタを使用する
  2. C++ で文字列の回文をチェックするには std::equal メソッドを使用する
  3. カスタム関数を使って C++ で文字列の回文をチェックする
C++ で文字列が回文かどうかをチェックする

この記事では、C++ で文字列が回文かどうかをチェックする方法をいくつか説明します。

C++ で文字列の回文をチェックするには rbegin/rend メソッドを用いて string のコピーコンストラクタを使用する

string クラスオブジェクトは演算子 == を用いた比較をサポートしており、回文パターンに適合する文字列を見つけるために利用することができます。回文は文字を逆順にマッチさせることを意味するので、rbeginrend のイテレータを用いて新しい文字列オブジェクトを構築する必要があります。残りの部分は必要に応じて if 文の中で構築することになります。

次の例では、2つの文字列、すなわち 1 単語の回文と複数単語の回文を宣言しています。スペースを含む文字列は定義パターンに合致しますが、このメソッドは回文として検出できないことに注意してください。

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::equal;
using std::remove;
using std::string;

int main() {
  string s1 = "radar";
  string s2 = "Was it a cat I saw";

  if (s1 == string(s1.rbegin(), s1.rend())) {
    cout << "s1 is a palindrome" << endl;
  } else {
    cout << "s1 is not a palindrome" << endl;
  }

  if (s2 == string(s2.rbegin(), s2.rend())) {
    cout << "s2 is a palindrome" << endl;
  } else {
    cout << "s2 is not a palindrome" << endl;
  }

  return EXIT_SUCCESS;
}

出力:

s1 is a palindrome
s2 is not a palindrome

C++ で文字列の回文をチェックするには std::equal メソッドを使用する

最後の実装はワンワード文字列でも動作しますが、オブジェクトのコピーを作成してその全範囲を比較するというオーバーヘッドを伴います。同じ string オブジェクト範囲の前半と後半を比較するには、std::equal アルゴリズムを利用することができます。std::equal は、与えられた 2つの範囲の要素が等しい場合、ブール値 true を返します。この関数は 2つ目の範囲については 1つのイテレータ s1.rbegin() を取るだけであることに注意してください。

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::equal;
using std::remove;
using std::string;

int main() {
  string s1 = "radar";
  string s2 = "Was it a cat I saw";

  equal(s1.begin(), s1.begin() + s1.size() / 2, s1.rbegin())
      ? cout << "s1 is a palindrome" << endl
      : cout << "s1 is not a palindrome" << endl;

  equal(s2.begin(), s2.begin() + s2.size() / 2, s2.rbegin())
      ? cout << "s2 is a palindrome" << endl
      : cout << "s2 is not a palindrome" << endl;

  return EXIT_SUCCESS;
}

出力:

s1 is a palindrome
s2 is not a palindrome

カスタム関数を使って C++ で文字列の回文をチェックする

これまでのメソッドでは、複数の単語を含む文字列では不足していましたが、カスタム関数を実装することで解決することができます。この例では、ブール値関数 checkPalindrome を用いて string& 引数を受け取り、その値をローカルの string 変数に格納しています。次に、このローカルオブジェクトは transform アルゴリズムで処理されて小文字に変換され、結果として erase-remove イディオムで空白文字をすべて削除します。最後に、if 文の条件で equal アルゴリズムを呼び出し、対応するブール値を返します。ただし、このメソッドは文字列がマルチバイト文字で構成されている場合に失敗することに注意してください。したがって、小文字変換メソッドは、すべての一般的な文字エンコーディングスキームをサポートするように実装されている必要があります。

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::equal;
using std::remove;
using std::string;

bool checkPalindrome(string& s) {
  string tmp = s;
  transform(tmp.begin(), tmp.end(), tmp.begin(),
            [](unsigned char c) { return tolower(c); });
  tmp.erase(remove(tmp.begin(), tmp.end(), ' '), tmp.end());

  if (equal(tmp.begin(), tmp.begin() + tmp.size() / 2, tmp.rbegin())) {
    return true;
  } else {
    return false;
  }
}

int main() {
  string s1 = "radar";
  string s2 = "Was it a cat I saw";

  checkPalindrome(s1) ? cout << "s1 is a palindrome" << endl
                      : cout << "s1 is not a palindrome" << endl;

  checkPalindrome(s2) ? cout << "s2 is a palindrome" << endl
                      : cout << "s2 is not a palindrome" << endl;

  return EXIT_SUCCESS;
}

出力:

s1 is a palindrome
s2 is a palindrome
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ String