切换除最高设置位之后的所有位

问题描述

除了最高设置位之后,如何切换数字的所有位?

例如: 让我们假设一个需要切换的 32 位数字。

00000000000000000010011110000100  // Input

00000000000000000001100001111011  // Expected

我怎样才能在 java/C++ 中实现这一点??

解决方法

我们可以执行以下操作。对于给定的 n = 10011110000100

  1. 我们将找到最小 2 的幂 v = 100...00 使得v > n
  2. 然后result = n ^ (v - 1)(注意b XOR 1 切换b

发生了什么:

n           =  10011110000100
v           = 100000000000000
v - 1       =  11111111111111
n ^ (v - 1) =  01100001111011

代码:

int n = 0b10011110000100;

int v = 1;

while (v <= n)
  v <<= 1;

int result = n ^ (v - 1);
,

你可以这样做:

public static int toggle(int n) {
  int m = n;
  m |= m >>> 1;
  m |= m >>> 2;
  m |= m >>> 4;
  m |= m >>> 8;
  m |= m >>> 16;
  return n ^ m;
}

具有2次幂的重复行,其目的是在m中设置n的最高有效设置位和所有低于它的有效位,可以用特殊指令替换以查找如果您可以访问此类内容,则为前导零的数量。

,

以下实现说明了 David Eisenstat 在提供任意大整数的语言(例如 Python 或 Ruby)中使用的 2 的幂的有效使用。换句话说,这些解决方案不是针对 32 位整数的硬连线。我用 21000 的输入测试了 Ruby 版本。

红宝石

def toggle(n)
  shift = 1
  m = n
  while (1 << shift) <= n
    m |= m >> shift
    shift <<= 1
  end
  m ^ n
end

Python

def toggle(n):
  shift = 1
  m = n
  while (1 << shift) <= n:
    m |= m >> shift
    shift <<= 1
  return m ^ n

您使用了 language-agnostic 标签,所以即使您在问题中提到了 C++ 和 Java,我也相信您的话。