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

【C++】直前の数値が1の補数と一致するかどうかを判定する方法


整数 n が与えられたとき、n の直前の数(n − 1)n の1の補数と一致しているかどうかを判定するのが、この問題の目的です。

具体例で問題を理解する

入力: 12
出力: No
解説: (12)10 = (1100)2
      直前の数 11 = (1011)2
      12 の1の補数 = (0011)2

入力: 4
出力: Yes
解説: 4 = (100)2
      直前の数 3 = (011)2
      4 の1の補数 = (011)2

単純なアプローチ

最も素直な方法は、n − 1 を計算し、n の各ビットを反転して得られる1の補数と直接比較することです。しかし、この方法ではビット列を生成・保持する必要があるため、時間とメモリの両面で非効率になります。

効率的な解法:2のべき乗だけが条件を満たす

実は、この条件を満たすのは2のべき乗のみです。
例えば n = 4 = (100)2 の場合、直前の数 3 = (011)2 であり、4 の1の補数も (011)2 となるため両者は一致します。
一般に n = 2k のとき、n − 1 は下位 k ビットがすべて1になり、n の1の補数(有効ビット幅内で反転した値)もまったく同じ形になるため、必ず等しくなります。

したがって、「n が2のべき乗かどうか」を判定できれば十分です。これはビット演算 (n & (n - 1)) == 0 を使えば定数時間 O(1) で求められます。n と n − 1 のANDを取ると、2のべき乗の場合にのみ結果が0になるという有名なテクニックです。

実装例

#include <iostream>
using namespace std;

bool sameBits(unsigned long int n){
    // n & (n - 1) が 0 なら n は 2 のべき乗
    if ((n & (n - 1)) == 0)
        return true;
    return false;
}

int main(){
    unsigned long int n = 64;
    if(sameBits(n))
        cout<<"Both are the same";
    else
        cout<<"Both aren't the same";
    return 0;
}

実行結果

Both are the same

n = 64 = 26 は2のべき乗であるため、直前の数 63 = (0111111)2 と 64 の1の補数 (0111111)2 は一致し、「Both are the same」と出力されます。


  1. C++で質素数(Frugal Number)を判定する方法【サンプルコード付き】

    この記事では、正の整数 N が与えられたときに、その数が質素数(Frugal Number)であるかどうかを判定するプログラムを C++ で作成する方法を解説します。 質素数とは? 質素数(FRUGAL NUMBER)とは、その数自身の桁数が、素因数分解による表現の桁数よりも厳密に大きい数のことです。 例:625 の場合 625 を素因数分解すると 54 となります。 625 自身の桁数:3 桁 54 の表現の桁数:2 桁 3 は 2 よりも厳密に大きいため、625 は質素数です。 最初のいくつかの質素数:125、128、243、256、343、512、625 など 問題を理解するための具

  2. C++で五胞体数(ペンタトープ数)を求める方法

    五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の