Algorithm 枚举设置了第k位的1到n之间的所有数字的最佳方法是什么?

Algorithm 枚举设置了第k位的1到n之间的所有数字的最佳方法是什么?,algorithm,data-structures,Algorithm,Data Structures,枚举设置了kth位的1到n之间的所有数字的最佳方法是什么 例如: 当n=12和k=1时,答案将是1,3,5,7,9,11 如果k=2,答案将是2、3、6、7、10、11 一个简单的方法是循环n并检查kth位是否已设置(通过检查num&(1),假设我们有n位,而位k固定为1,所以我们寻找的数字看起来像xxxx1xxxx,所以我们只需要生成所有具有(n-1)位的数字 例如,如果我们有3个位,并且我们希望设置位2,那么我们只需要生成2^(n-1)=4个数字,最后的数字看起来像:x1x 所以这些数字是0

枚举设置了
kth
位的1到
n
之间的所有数字的最佳方法是什么

例如:
n=12
k=1
时,答案将是
1,3,5,7,9,11

如果
k=2
,答案将是
2、3、6、7、10、11


一个简单的方法是循环
n
并检查
kth
位是否已设置(通过检查
num&(1),假设我们有n位,而位k固定为1,所以我们寻找的数字看起来像
xxxx1xxxx
,所以我们只需要生成所有具有(n-1)位的数字

例如,如果我们有3个位,并且我们希望设置位2,那么我们只需要生成2^(n-1)=4个数字,最后的数字看起来像:x1x

所以这些数字是0(00),1(01),2(10),3(11)->加上第2位,我们寻找的最终数字是2(010),3(011),6(110),7(111)

伪代码:

   int n = ...//User input
   int bit = numberOfBitUsed(n)
   for(int i = 0; i < (1<<bit); i++){
       int number = generateNumber(i, k);
       if(number > n){
          break;
       }

   }

如果您增加该数字,并且应该有一个从k以下部分到k以上部分的进位,则进位将传播并保留第k位0,否则它将保持1

因此,您只需重新打开第k位:

x = (x + 1) | (1 << k);

x=(x+1)|(1您将工作减半,因为您删除了一位。并增加了一些额外的开销。不确定这是否真的更快。@KarolyHorvath您可能是对的!但是,我们可以在O(1)中生成数字(如我更新的答案中所示),因此有改进的机会:)似乎正确:)这应该比我的+1更好
x = (x + 1) | (1 << k);
for (int x = 1 << k; x < n; x = (x + 1) | (1 << k))
    print(x); // or whatever