C++で数値Nが基数b表記において1から始まるかどうかを判定する方法
本記事では、数値Nと基数bが与えられたとき、「Nを基数bで表記すると先頭の桁が1になるかどうか」を判定する方法をC++で解説します。
まず具体例を見てみましょう。数値6を2進数で表すと「110」であり、先頭は1です。4進数で表すと「12(4)」となり、これも先頭が1です。このように、同じ数でも基数によって表記が変わり、先頭の桁が1になる場合とならない場合があります。
判定の考え方(数学的な背景)
数値Nを基数bで表すと、m+1桁の数列 dm dm-1 … d0 になり、次の関係が成り立ちます。
dm × bm + dm-1 × bm-1 + … + d0 × b0 = N
ここで、先頭の桁 dm が「1」であるような数の範囲を考えます。最小値は 1 × bm = bm です。一方、最大値は残りの下位の桁がすべて最大値(b − 1)になった場合で、bm + (bm − 1) = 2 × bm − 1 となります。
つまり、Nが基数b表記で1から始まる ⟺ ある整数mについて bm ≤ N ≤ 2 × bm − 1 が成り立つということです。
さらに、探索すべきmの範囲には上限があります。どんな基数で表記しても、その桁数は2進数表記の桁数を超えません。2進数では数が0と1だけで表され、その桁数は常に最も長くなるためです。Nの2進数表記における桁数は ⌊log2N⌋ + 1 なので、mは1から ⌊log2N⌋ の範囲を調べれば十分です。
以上より、m = 1 から ⌊log2N⌋ まで順番に確認し、いずれかのmで bm ≤ N ≤ 2 × bm − 1 が成立すれば「1から始まる」(true)、どこでも成立しなければ「1から始まらない」(false)と判定できます。
C++による実装例
#include <iostream>
#include <cmath>
using namespace std;
// numberをbase進法で表したとき、先頭の桁が1かどうかを判定する
bool isStartWithOne(int number, int base) {
int m = log2(number); // 探索範囲の上限(2進数表記の桁数 - 1)
for (int i = 1; i <= m; i++) {
// numberが [base^i, 2*base^i - 1] の範囲に入れば1始まり
if (number >= pow(base, i) && number <= 2 * pow(base, i) - 1)
return true;
}
return false;
}
int main() {
int num = 19, base = 16;
if (isStartWithOne(num, base)) {
cout << "Can be represented";
} else {
cout << "Can not be represented";
}
return 0;
}
実行結果
Can be represented
この例では num = 19、base = 16 としています。19を16進数で表すと「13」であり、先頭の桁が1なので「Can be represented(1から始まる表記が存在する)」と出力されます。
計算量
ループは最大 ⌊log2N⌋ 回繰り返されるため、時間計算量は O(log N) です。追加のメモリも不要で、空間計算量は O(1) となります。
-
C++でNが五角数(ペンタゴナル数)かどうかを判定するプログラム
五角数とはある整数 N が与えられたとき、それが五角数(ペンタゴナル数)であるかどうかを判定するのが本記事の目的です。五角数とは、点を並べることで正五角形の形を描くことができる数のことです。これらの数は、五角形を構成する頂点や点として表現できます。五角数の例としては、次のような数列が挙げられます。1, 5, 12, 22, 35, 51, 70, 92 …五角数を判定する公式ある数が五角数かどうかは、以下の公式を利用して確認できます。p(n) = (3 × n² − n) / 2ここで、n は五角形を構成する点の個数を表します。この式から得られる値が順に 1, 5, 12, 22, 35… と
-
アームストロング数を判定するC++プログラムの書き方と解説
アームストロング数とはアームストロング数(Armstrong Number)とは、各桁の数字を「総桁数」乗した値の合計が、元の数そのものと等しくなる数のことです。例えば、153は3桁の数なので、各桁を3乗して足し合わせると元の数に戻ります。主なアームストロング数の例は以下の通りです。3 = 3^1 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 371 = 3^3 + 7^3 + 1^3 = 27 + 343 + 1 = 371 407 = 4^3 + 0^3 + 7^3 = 64 + 0 + 343 = 407この性質を利用すると、任意の整数がアームスト