C言語でポインタを使って文字列が回文かどうかを判定する方法
はじめに
文字列 s が与えられたとき、その文字列が回文(パリンドローム)であるかどうかを判定することを考えます。ここでは、C言語のポインタを使ってこの問題を解いていきます。
例えば、入力が s = "racecar" の場合、出力は True(1) になります。「racecar」は前から読んでも後ろから読んでも同じ文字列だからです。
解法のアプローチ
この問題は、2つのポインタを文字列の両端に置き、中央に向かって互いに近づけていくことで効率的に判定できます。手順は以下の通りです。
- 文字列の長さを取得する
- ポインタ
forwardを文字列の先頭文字に向ける - ポインタ
reverseを文字列の末尾文字に向ける reverseの位置がforwardの位置以上である間、以下を繰り返す- 両ポインタが指す文字が一致していれば、
forwardを1つ進め、reverseを1つ戻す - 一致しなければループを抜ける
- 両ポインタが指す文字が一致していれば、
- 最終的に
forwardの位置がreverseの位置以上であれば回文としてTrueを返す - そうでなければ
Falseを返す
実装例
それでは、実際のコードを見て理解を深めましょう。
#include <stdio.h>
#include <string.h>
int solve(char *string){
int length;
char *forward, *reverse;
length = strlen(string);
forward = string;
reverse = forward + length - 1;
for (forward = string; reverse >= forward;) {
if (*reverse == *forward) {
reverse--;
forward++;
} else
break;
}
if (forward > reverse)
return 1;
else
return 0;
}
int main(){
char string[] = "racecar";
printf("%d", solve(string));
}入力
"racecar"
出力
1
コードの解説
solve 関数では、まず strlen で文字列の長さを求め、先頭へのポインタ forward と末尾へのポインタ reverse を設定します。次に for ループの中で、*forward と *reverse(各ポインタが指す文字)を比較し、一致すれば両ポインタを中央方向へ移動させます。途中で不一致が見つかれば即座にループを抜けます。
ループ終了後、forward > reverse が成立している場合はすべての文字が一致したことを意味するため、回文として 1(True) を返します。
このアルゴリズムの計算量は O(n/2)、つまり O(n) であり、追加の配列など余分なメモリも不要なため、非常に効率的な方法と言えます。
-
【C言語】再帰を使って配列が回文かどうかを判定するプログラム
配列 arr[n](n は配列のサイズ)が与えられたとき、再帰を用いてその配列が回文かどうかを判定するのが本記事のテーマです。回文とは、前から読んでも後ろから読んでも同じになる並びのことで、「MADAM」や「NAMAN」などが代表的な例です。配列が回文かどうかを調べるには、先頭と末尾から順に要素を比較していきます。再帰的なアプローチでも同様に、start と end の値を更新しながら比較を続けます。start と end が交差(すれ違う)すれば回文と判定でき、途中で要素が一致しなかった場合はそこで処理を打ち切り、false を返します。入力例と出力例入力: arr[] = { 2, 3,
-
C++のSTLを使って配列が回文かどうかを判定するプログラム
整数 n 個からなる配列 arr[n] が与えられたとき、「その配列は回文(パリンドローム)か?」を判定するのが本稿のテーマです。C++ の STL(標準テンプレートライブラリ)を活用して、この問題をシンプルに解いていきます。 STLとは STL(Standard Template Library)は、C++ に用意されたテンプレートクラスの集合体で、スタック・キュー・リストといったデータ構造や、ソート・反転などの便利な関数を提供します。これらを活用するには、テンプレートクラスに関する基本的な知識が必要です。本稿では、STL の reverse() 関数を使って配列を反転させています。 回文と