C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++の基数変換法を使って数値がkの冪乗かどうかを判定する方法

はじめに

この記事では、ある数値と値 k が与えられたとき、その数値が k の冪乗であるかどうかを「基数変換法(底の変換)」を用いて判定するC++プログラムを紹介します。

例として、数値が 27、k = 3 のケースを考えてみましょう。27 を 3 進法で表すと「1000」になります。このように基数変換を行った結果、「1」がちょうど1回だけ現れ、それ以外の桁がすべて「0」であれば、その数値は k の冪乗であると判断できます。

アルゴリズムの手順

この問題は、以下の手順に従って解くことができます。

  • フラグ(flag)を false として初期化する
  • number > 0 の間、手順3〜6を繰り返す
  • digit := number mod k を計算する(k進法での現在の桁を取得)
  • digit > 1 の場合は false を返す
  • digit が 1 の場合、flag がすでに true であれば false を返し、そうでなければ flag := true とする
  • number := number / k として更新する
  • ループを抜けたら true を返す

このアルゴリズムの計算量は O(logk n) であり、非常に効率的です。

サンプルコード(C++)

#include <iostream>
#include <cmath>
using namespace std;
bool isPowerOfK(int num, int k) {
    bool flag = false;
    while (num > 0) {
        int digit = num % k; // k進法での現在の桁を取得
        if (digit > 1) // 桁が0でも1でもない場合、kの冪乗ではない
        return false;
        if (digit == 1) {
            if (flag)
                return false;
            flag = true;
        }
        num /= k;
    }
    return true;
}
int main() {
    int number = 27, K = 3;
    if(isPowerOfK(number, K)){
        cout << number << " is power of " << K;
    } else {
        cout << number << " is not power of " << K;
    }
}

実行結果

27 is power of 3

コードの解説

isPowerOfK 関数では、数値を k で割りながら各桁を順番に調べていきます。途中で「1」以外の非ゼロの桁が見つかった時点で、その数値は k の冪乗ではないと即座に判定できます。また、「1」が2回以上現れた場合も冪乗ではないため、flag 変数によって「1」の出現を管理しています。

上記の例では、27 を 3 進法で表すと「1000」となり、「1」が1回だけ出現するため、27 は 3 の冪乗(3³)であると正しく判定されています。

  1. C++で解く!Nの階乗のB進表現における末尾ゼロの個数の求め方

    はじめにこの記事では、与えられた数Nの階乗(N!)を基数Bで表したとき、末尾にいくつのゼロが連続するかを求める問題について詳しく解説します。問題の例入力 : N = 7、基数 = 2 出力 : 4 説明 : fact(7) = 5040(10進数)であり、2進数では「1001110110000」となるため、末尾にゼロが4個並びます。 入力 : N = 11、基数 = 5 出力 : 2 説明 : fact(11) = 39916800(10進数)であり、5進数では「40204314200」となるため、末尾にゼロが2個並びます。基数変換のおさらいまず、10進数から他の基数へ数値を変換する手順を確

  2. C++で解く!Nの階乗の16進数表現における末尾のゼロの個数の求め方

    この記事では、与えられた整数Nの階乗(N!)を16進数で表したとき、末尾に何個のゼロが連続するかを求める問題について詳しく解説します。 入力 : N = 7 出力 : 1 説明 : fact(7) = 5040(10進数)で、16進数では13B0となり、末尾のゼロは1個です。 入力 : N = 11 出力 : 2 説明 : fact(11) = 39916800(10進数)で、16進数では2611500となり、末尾のゼロは2個です。 10進数から16進数への変換のおさらい まず、任意の10進数を別の基数へ変換する手順をおさらいしましょう。ここでは、(5040)10 を16進数に変換する例を