ホームページ >バックエンド開発 >C++ >一番左の未設定ビットを設定します

一番左の未設定ビットを設定します

WBOY
WBOY転載
2023-09-10 17:05:021151ブラウズ

一番左の未設定ビットを設定します

この記事は、指定された数値の左端の未設定ビットを設定する方法を見つけることを目的としています。最上位の設定ビットの後の最初の未設定ビットは、一番左の未設定ビットとみなされます。

###問題文###

数値 n が与えられた場合、タスクは、数値の 2 進展開の未設定の左端のビットを 1 に設定することです。他のすべてのビットは変更しないでください。元の数値のすべてのビットが設定されている場合は、その数値が返されます。

リーリー リーリー

説明

の中国語訳は次のとおりです:

説明

46 のバイナリ展開 = 101110.

左端の未設定ビットは 101110 です。

下線付きのビットを設定すると、111110 が得られます。これは 62 のバイナリ展開です。

したがって、答えは 62.

リーリー リーリー

説明

の中国語訳は次のとおりです:

説明

11 のバイナリ展開 = 1011.

左端の未設定ビットは 1011 です。

下線付きのビットを変更すると、15 をバイナリ展開した 1111 が得られます。

リーリー リーリー

説明

の中国語訳は次のとおりです:

説明

30 のバイナリ展開 = 11110.

左端の未設定ビットは 11110 です。

左端の未設定ビットを設定すると、31 を 2 進展開した 11111 が得られます。

リーリー リーリー

説明

の中国語訳は次のとおりです:

説明

7 のバイナリ展開 = 111.

すべてのビットが設定されているため、左端の未設定のビットはありません。したがって、答えは元の数字と同じになります。

解決方法

    すべてのビットが設定されているかどうかを確認します。その場合は、元の数値を答えとして返します。
  • ビットごとの AND 演算子を使用して、最後に設定されていないビットの位置を見つけ、カウンターを更新します。
  • カウンタに対応するビットを設定します。
  • 答えを表示します。
  • すべてのビットが設定されているかどうかを確認する

ここでの考え方は、ビットを 1 つ追加することで、すべてのビットが設定されていれば入力数値は 2 の完全二乗になるということです。したがって、次の式は、数値のすべてのビットが設定されているかどうかを判断します。 n & (n 1) == 0;

例を通してこれを理解しましょう。

数値を 5 にします。5 のすべてのビットが設定されているかどうかを確認する必要があります。

n = 3011 の中国語訳: 011

Thus it is safe to conclude that all the bits of n are already set and we return the number as it is.

找到最左边未设置的位

如果AND操作的输出不等于零,则继续查找最左边未设置的位。首先生成一个位数与给定整数相等的数字。新数字的最左边位最初设置为1。

然后,我们运行一个循环,从最左边的1位开始,向右搜索第一个0,通过对给定数字和新数字进行位与运算来实现。当位与运算的结果为0时,我们返回第一个未设置的最左边位的位置pos。

To Set the Leftmost Unset Bit

Generate a new number in which only the bit corresponding to pos is set. Perform bitwise OR operation between this new number and the original number.

Algorithm

的中文翻译为:

算法

Function all_bits_set()

  • 计算 n & (n + 1)。

  • If result == 0, return true.

  • 否则返回 false。

Function find_leftmost_unset_bit()

  • Initialize m = 1, pos = 0.

  • while (n > m)

    • 左移 m 1 位

  • 将 m 右移 1 位,以使其对应于 n 的最高有效位。

  • while ((n & m) != 0)

    • 将 m 右移 1 位

    • pos++

  • 一旦循环中断,我们就可以得到最高有效位(MSB)中最左边未设置的位的位置。

  • 返回 log2(n) - pos,即从最低有效位开始的位位置。

函数 set_leftmost_unset_bit()

  • 初始化 k = 1

  • Function Call find_leftmost_unset_bit().

  • k = k

  • Compute n | k.

  • Update n.

Function main()

  • 初始化 n

  • Function Call all_bits_set()

  • 函数调用 find_leftmost_unset_bit()

  • 调用函数set_leftmost_unset_bit()

  • 显示 n

示例:C++程序

这个程序通过将输入数字 n 的二进制展开中最左边未设置的位设置为 1 来修改它。它使用位运算符 OR,左移和右移运算符以及位与运算符来实现其目标。

// A C++ program to set the left most unset bit of a number. If all the bits of the given number are already set, it returns the number as it is.
#include <iostream>
#include <cmath>
using namespace std;
// function to check if all bits of the given number are already set
// if all bits of n are set, n + 1 will be a power of 2.
bool all_bits_set(int n){
   if ((n & (n + 1)) == 0)    {
      return true;
   }
   return false;
}

// function to find the position of the leftmost unset bit from the LSB.
int find_leftmost_unset_bit(int n){
   int m = 1, pos = 0;
   while (n > m){
      m = m << 1;
   }
   m = m >> 1; // to make the number of digits in m equal to number of digits in n
   
   // the following loop executes till the first zero is encountered, starting from the msb
   while ((n & m) != 0){
      m = m >> 1;
      pos++;
   }
   
   // since pos is the position of the unset bit from the MSB we return log2(n) - pos which is the location of the leftmost unset bit from the LSB.
   return log2(n) - pos;
}

// function to set the leftmost unset bit from the LSB.
void set_leftmost_unset_bit(int &n){
   int k = 1;
   int pos = find_leftmost_unset_bit(n);
   k = k << (pos); // left shift k by pos
   n = n | k; // to set the leftmost unset bit
}

// main function
int main(){
   int n = 46;
   cout << "Input Number: "<< n << endl;
   if (all_bits_set(n))    {
      cout << n << endl;
      return 0;
   }
   set_leftmost_unset_bit(n);
   cout << "Number after setting the Leftmost Unset Bit: " << n << endl; // display the updated number
   return 0;
}

输出

Input Number: 46
Number after setting the Leftmost Unset Bit: 62

时间和空间分析

时间复杂度:O(log2(n)),因为在函数find_leftmost_unset_bit()中,我们可能需要遍历二进制展开式的所有log2(n)位数来找到最左边的未设置位。

Space Complexity: O(1), as constant space is always used in the implementation.

Conclusion

本文讨论了一种寻找并设置给定数字最左边未设置位的方法。如果数字的所有位已经设置,我们将返回该数字。否则,为了设置该位,我们使用位左移和右移运算符生成一个新的位模式,并使用位或运算符计算结果。解决方案的概念、多个示例、使用的算法、C++程序解决方案以及时间和空间复杂度分析都被详细解释,以便更深入地理解。

n 1 = 4 n & (n 1)
100 000

以上が一番左の未設定ビットを設定しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はtutorialspoint.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。