C++でイビルナンバー(悪数)とオディアスナンバーを判定する方法
イビルナンバーとオディアスナンバーとは?
この問題では、整数 N が与えられ、その数がイビルナンバー(Evil Number)かオディアスナンバー(Odious Number)かを判定します。
イビルナンバー:2進表現における「1」の個数が偶数である正の整数のことです。
例:5、17
オディアスナンバー:2進表現における「1」の個数が奇数である正の整数のことです。
例:4、6
具体例で問題を理解しよう
入力:N = 65
出力:イビルナンバー
解説:
65 の2進表現は 1000001 です。「1」が2つ含まれており、その個数は偶数なので、65 はイビルナンバーであると判定できます。
解法のアプローチ
シンプルな解き方は次の通りです。
- 対象となる数の2進表現を求める。
- 2進表現の中に含まれる「1」の個数を数える。
- 個数が偶数であればイビルナンバー、奇数であればオディアスナンバーと判定する。
なお、C++ では除算と剰余演算を使って下位ビットから順に調べる方法が基本ですが、GCC や Clang では組み込み関数 __builtin_popcount(n) を使うことで、「1」の個数を1行で取得することも可能です。
解法の動作を示すプログラム
サンプルコード
#include <iostream>
using namespace std;
int isEvilNumber(int n) {
int count = 0;
while (n != 0) {
int r = n % 2;
if(r == 1)
count++;
n = n / 2;
}
if (count % 2 == 0)
return 1;
else
return 0;
}
int main(void)
{
int num = 2049;
if (isEvilNumber(num) )
cout<<"The number "<<num<<" is an Evil Number";
else
cout<<"The number "<<num<<" is an Odious Number";
return 0;
}
出力結果
The number 2049 is an Evil Number
プログラムのポイント
このコードでは、isEvilNumber() 関数内で while ループを使い、数値を2で割りながら余りを確認しています。余りが1であればカウントを増やし、最終的にカウントが偶数かどうかで判定を行います。
2049 の2進表現は 100000000001 であり、「1」が2つ(偶数個)含まれるため、イビルナンバーとして出力されます。
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の
-
C++で学ぶ式ツリー(Expression Tree)の基本と具体例
式ツリーとは何か式ツリー(Expression Tree)とは、二分木の一種であり、木の各ノードが「演算子」または「オペランド(被演算子)」のいずれかで構成される特殊なデータ構造です。数式を木構造として表現することで、コンパイラや電卓アプリなどが数式を効率的に解析・評価できるようになります。ノードの役割式ツリーにおける各ノードは、次のように役割が分かれています。葉ノード(リーフノード):オペランド(数値や変数)を表します。非葉ノード(内部ノード):演算子(+、-、*、/ など)を表します。つまり、計算の対象となる値は必ず葉に配置され、それらをどのように処理するかを示す演算子が親ノードとして上に