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

C++で指定した数値がスパース数かどうかを判定する方法

この記事では、与えられた数値がスパース数(sparse number)であるかどうかを判定する方法を解説します。

スパース数とは?

スパース数とは、その数値を2進数で表したときに、「1」が2つ以上連続して現れない数のことを指します。

例として、数値 72 を考えてみましょう。72を2進数で表すと 01001000 となります。この2進表現には連続する「1」が存在しないため、72はスパース数であるといえます。

判定アルゴリズムの考え方

スパース数の判定は、ビット演算を使うと非常にシンプルに行えます。手順は以下の通りです。

対象の数値を n としたとき、
1. n を右に1ビットシフトします。
2. 元の n との間でビットごとのAND(&)を計算します。
3. 結果が 0 であればスパース数、そうでなければスパース数ではありません。

これは、隣り合うビット同士を比較することで、連続する「1」が存在するかどうかを検出できるためです。もし連続する「1」があれば、n と (n >> 1) の両方で同じ位置に「1」が立ち、ANDの結果が0以外になります。

C++での実装例

#include <iostream>
using namespace std;

bool isSparseNumber(int n) {
    int res = n & (n >> 1);
    if(res == 0)
        return true;
    return false;
}

int main() {
    int num = 72;
    if(isSparseNumber(num)){
        cout << "This is sparse number";
    } else {
        cout << "This is not sparse number";
    }
}

実行結果

This is sparse number

まとめ

このように、右シフトとビットごとのANDを組み合わせることで、O(1) の計算量で数値がスパース数かどうかを効率的に判定できます。ループで各ビットを順番に調べる方法もありますが、ビット演算を活用すればコードも簡潔になり、処理速度の面でも有利です。

  1. C++で巨大な数値が25で割り切れるかどうかを判定する方法

    本記事では、ある数値が25で割り切れるかどうかを判定する方法を解説します。扱う数値が非常に大きい(桁数が多い)場合、通常の整数型では表現しきれないため、数値を文字列として受け取って処理します。25の倍数の判定ルール数値が25で割り切れるかどうかは、下2桁だけを見れば判定できます。具体的には、以下のいずれかの条件を満たしていれば、その数は25で割り切れます。下2桁が「00」である下2桁の数値自体が25で割り切れる(00、25、50、75)これは、100が25で割り切れるため、下2桁より上の部分は必ず25の倍数になるという性質によるものです。サンプルコード#include <bits/std

  2. C++で大きな数が11で割り切れるかどうかを判定する方法

    本記事では、C++を用いて、ある数が11で割り切れるかどうかを判定する方法を解説します。ここで扱うのは非常に大きな数であるため、int 型や long long 型といった標準的な整数型には収まりません。そこで、数値を文字列として受け取り、桁ごとに処理を行います。 11の倍数判定法とは ある整数が11で割り切れるかどうかは、次の有名な判定法で簡単に確認できます。 左から順に各桁を見て、奇数番目の桁の合計と偶数番目の桁の合計をそれぞれ求める。 両者の差が0、または11の倍数であれば、その数は11で割り切れる。 特に、奇数番目の桁の合計と偶数番目の桁の合計が一致していれば、差は必ず0になるた