C++で文字列を使わずに回文数(パリンドローム)を判定する方法
この記事では、非負の整数 num が与えられたとき、それが回文数(パリンドローム)であるかどうかを判定する方法を解説します。ポイントは、文字列に変換せずに数値演算だけで判定するという点です。
例えば、入力が 1331 の場合、逆から読んでも「1331」となるため、出力は true になります。
アルゴリズムの考え方
文字列を使わずに回文を判定するには、元の数値を数学的に反転(逆順に並べ替え)し、元の数値と一致するかを比較します。手順は以下の通りです。
- 結果を格納する変数
retを 0 で初期化する - 元の値を保存するため、
x := numとしてコピーしておく num > 0の間、以下を繰り返すd := num mod 10で最下位桁を取り出すret := ret * 10で既存の桁を左にシフトするret := ret + dで取り出した桁を追加するnum := num / 10で処理済みの桁を削除する
- ループ終了後、
x == retであればtrueを返す
この手法では、1の位から順に桁を取り出して反転後の数値を組み立てていくため、to_string() などの文字列操作が一切不要になります。
C++での実装例
それでは、実際のコードを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool solve(int num) {
int ret = 0;
int x = num;
while(num > 0){
int d = num % 10;
ret *= 10;
ret += d;
num /= 10;
}
return x == ret;
}
};
main() {
Solution ob;
cout << (ob.solve(1331));
}入力
1331
出力
1
処理の流れを追ってみる
入力 1331 の場合、ループは以下のように進行します。
| 繰り返し | d(取り出した桁) | ret(反転中の数値) | num(残りの数値) |
|---|---|---|---|
| 初期状態 | - | 0 | 1331 |
| 1回目 | 1 | 1 | 133 |
| 2回目 | 3 | 13 | 13 |
| 3回目 | 3 | 133 | 1 |
| 4回目 | 1 | 1331 | 0 |
最終的に ret = 1331 となり、元の値 x = 1331 と一致するため、関数は true(出力では 1)を返します。
注意点
- 負の数は回文にならない:符号があるため、-121 を反転しても 121- とは一致しません。本アルゴリズムは非負整数を前提としています。
- オーバーフローに注意:反転後の数値が
intの最大値(2,147,483,647)を超える可能性がある場合は、long long型の使用やオーバーフローチェックを検討しましょう。 - 計算量:桁数分だけループが回るため、時間計算量は O(log₁₀ n)、空間計算量は O(1) と非常に効率的です。
このように、剰余演算と除算を組み合わせるだけで、文字列に頼らず簡潔に回文判定を実装できます。競技プログラミングやコーディング面接でも頻出のテクニックなので、ぜひ覚えておきましょう。
-
C++で解く「ジャンプゲームV」:メモ化再帰による最大訪問インデックス数の求め方
問題の概要整数型の配列 arr と整数 d が与えられます。1ステップごとに、インデックス i から次の場所へジャンプできます。右方向: i + x(ただし i + x < n、かつ x は 1 以上 d 以下)左方向: i - x(ただし i - x >= 0、かつ x は 1 以上 d 以下)ここで n は配列のサイズです。さらに重要な制約として、インデックス i から j へジャンプできるのは、arr[i] > arr[j] であり、かつ i と j の間にあるすべてのインデックス k に対して arr[i] > arr[k] を満たす場合のみです。つまり、より低
-
数値が回文数(パリンドローム)かどうかを判定するC++プログラム
回文数(パリンドローム)とは、桁の並びを逆に読んでも元の値と変わらない数のことです。その対称的な性質から「対称数」と呼ばれることもあります。例えば、12321、1551、11 などの数は、桁を逆順に並べ替えても値が変化しないため、回文数です。本記事では、与えられた数値が回文数であるかどうかを判定するC++プログラムを紹介し、その仕組みを詳しく解説します。プログラム例#include<iostream> using namespace std; void palindrome(int num) { int rev=0,val; val = num; while