📜  下一个更高的数字,且设置的位数相同

📅  最后修改于: 2021-04-27 18:46:01             🧑  作者: Mango

给定数字x,请在二进制表示形式中查找具有1位相同数字的下一个数字。
例如,考虑x = 12,其二进制表示形式为1100(不包括32位计算机上的前导零)。它包含两个逻辑1位。具有两个逻辑1位的下一个更高的数字是17(10001 2 )。
算法:
当我们观察从0到2 n – 1的二进制序列(n是位数)时,最右边的位(最低有效位)比最左边的位变化快。这个想法是在x中找到最右边的1的字符串,并将模式移到最右端,除了模式中最左边的位。将模式中最左边的位(忽略的位)向x的左部分移动一个位置。一个例子可以更清楚地说明,

x = 156

10

x = 10011100

(2)

10011100
00011100 - right most string of 1's in x
00000011 - right shifted pattern except left most bit ------> [A]
00010000 - isolated left most bit of right most 1's pattern
00100000 - shiftleft-ed the isolated bit by one position ------> [B]
10000000 - left part of x, excluding right most 1's pattern ------> [C]
10100000 - add B and C (OR operation) ------> [D]
10100011 - add A and D which is required number 163

(10)
经过少量实例练习后,它很容易理解。使用以下给定的程序生成更多集合。
程序设计:
我们需要注意一些二进制数的事实。表达式x&-x将隔离x中最右边的设置位(确保x将对负数使用2的补码形式)。如果将结果加到x,将重置x中最右边的1的字符串,并将设置此1的模式左边的立即数“ 0”,这是上述说明的[B]部分。例如,如果x = 156,则x&-x将得到00000100,将此结果加到x上将得出10100000(请参阅D部分)。我们留下了1的模式的右移部分(上述说明的A部分)。
有多种方法可以实现A部分。右移本质上是一种除法运算。我们的除数应该是多少?显然,它应该是2的倍数(避免右移0.5个错误),并且应该将最右边的1的模式转移到最右端。表达式(x&-x)将用于除数的目的。在数字X和用于重置最右边的位的表达式之间的EX-OR运算将隔离最右边的1的模式。
校正因子:
注意,我们将最右边的设置位添加到位模式中。加法运算引起位位置的偏移。二进制系统的权重为2,一移位会导致系数增加2。由于增加的数字(代码中的rightOnesPattern )被使用了两次,因此错误传播了两次。该错误需要纠正。向右移动2个位置将校正结果。
该方案的俗称为s AMEň华氏度ØNE B的。

C++
#include
 
using namespace std;
 
typedef unsigned int uint_t;
 
// this function returns next higher number with same number of set bits as x.
uint_t snoob(uint_t x)
{
 
  uint_t rightOne;
  uint_t nextHigherOneBit;
  uint_t rightOnesPattern;
 
  uint_t next = 0;
 
  if(x)
  {
 
    // right most set bit
    rightOne = x & -(signed)x;
 
    // reset the pattern and set next higher bit
    // left part of x will be here
    nextHigherOneBit = x + rightOne;
 
    // nextHigherOneBit is now part [D] of the above explanation.
 
    // isolate the pattern
    rightOnesPattern = x ^ nextHigherOneBit;
 
    // right adjust pattern
    rightOnesPattern = (rightOnesPattern)/rightOne;
 
    // correction factor
    rightOnesPattern >>= 2;
 
    // rightOnesPattern is now part [A] of the above explanation.
 
    // integrate new pattern (Add [D] and [A])
    next = nextHigherOneBit | rightOnesPattern;
  }
 
  return next;
}
 
int main()
{
  int x = 156;
  cout<<"Next higher number with same number of set bits is "<


Java
// Java Implementation on above approach
class GFG
{
     
// this function returns next higher
// number with same number of set bits as x.
static int snoob(int x)
{
 
int rightOne, nextHigherOneBit, rightOnesPattern, next = 0;
 
if(x > 0)
{
 
    // right most set bit
    rightOne = x & -x;
 
    // reset the pattern and set next higher bit
    // left part of x will be here
    nextHigherOneBit = x + rightOne;
 
    // nextHigherOneBit is now part [D] of the above explanation.
 
    // isolate the pattern
    rightOnesPattern = x ^ nextHigherOneBit;
 
    // right adjust pattern
    rightOnesPattern = (rightOnesPattern)/rightOne;
 
    // correction factor
    rightOnesPattern >>= 2;
 
    // rightOnesPattern is now part [A] of the above explanation.
 
    // integrate new pattern (Add [D] and [A])
    next = nextHigherOneBit | rightOnesPattern;
}
 
return next;
}
 
// Driver code
public static void main (String[] args)
{
    int x = 156;
    System.out.println("Next higher number with same" +
                    "number of set bits is "+snoob(x));
}
}
 
// This code is contributed by mits


Python 3
# This function returns next
# higher number with same
# number of set bits as x.
def snoob(x):
     
    next = 0
    if(x):
         
        # right most set bit
        rightOne = x & -(x)
         
        # reset the pattern and
        # set next higher bit
        # left part of x will
        # be here
        nextHigherOneBit = x + int(rightOne)
         
        # nextHigherOneBit is
        # now part [D] of the
        # above explanation.
        # isolate the pattern
        rightOnesPattern = x ^ int(nextHigherOneBit)
         
        # right adjust pattern
        rightOnesPattern = (int(rightOnesPattern) /
                            int(rightOne))
         
        # correction factor
        rightOnesPattern = int(rightOnesPattern) >> 2
         
        # rightOnesPattern is now part
        # [A] of the above explanation.
         
        # integrate new pattern
        # (Add [D] and [A])
        next = nextHigherOneBit | rightOnesPattern
    return next
 
# Driver Code
x = 156
print("Next higher number with " +
      "same number of set bits is",
                          snoob(x))
 
# This code is contributed by Smita


C#
// C# Implementation on above approach
using System;
class GFG
{
     
// this function returns next higher
// number with same number of set bits as x.
static int snoob(int x)
{
 
    int rightOne, nextHigherOneBit,
        rightOnesPattern, next = 0;
     
    if(x > 0)
    {
     
        // right most set bit
        rightOne = x & -x;
     
        // reset the pattern and set next higher bit
        // left part of x will be here
        nextHigherOneBit = x + rightOne;
     
        // nextHigherOneBit is now part [D]
        // of the above explanation.
     
        // isolate the pattern
        rightOnesPattern = x ^ nextHigherOneBit;
     
        // right adjust pattern
        rightOnesPattern = (rightOnesPattern) / rightOne;
     
        // correction factor
        rightOnesPattern >>= 2;
     
        // rightOnesPattern is now part [A]
        // of the above explanation.
     
        // integrate new pattern (Add [D] and [A])
        next = nextHigherOneBit | rightOnesPattern;
    }
    return next;
}
 
// Driver code
static void Main()
{
    int x = 156;
    Console.WriteLine("Next higher number with same" +
                      "number of set bits is " + snoob(x));
}
}
 
// This code is contributed by mits


PHP
>= 2;
     
        // rightOnesPattern is now part [A]
        // of the above explanation.
     
        // integrate new pattern (Add [D] and [A])
        $next = $nextHigherOneBit | $rightOnesPattern;
    }
 
    return $next;
}
 
// Driver Code
$x = 156;
echo "Next higher number with same " .
     "number of set bits is " . snoob($x);
 
// This code is contributed by ita_c
?>


Javascript


输出:

Next higher number with same number of set bits is 163

用法:查找/生成子集。
变化:

  1. 编写一个程序,找到一个比给定的数字小得多的数字,并且逻辑位数为1? (非常简单)
  2. 如何计算或生成给定集中可用的子集?

参考:

  1. 一个不错的演示。
  2. 沃伦(Warren)的Hackers Delight(一本精巧的短本,介绍各种位魔术算法,对于发烧友来说是必不可少的)
  3. Harbison和Steele撰写的CA参考手册(有关标准C的好书,您可以在此处访问本文的代码部分)。