k的下一个词典排列,约束大于或等于数字g'

时间:2016-05-23 12:31:02

标签: algorithm bit-manipulation

我有一个掩码k,例如01100011。 我有一个索引j,它表示我想要保存的最高有效位,例如在01100011中取011 ==> J = 2。 我希望找到k的最小词典排列大于g =((k>(k.len-1-j))+ 1)<(k.len-1-j) )使用位操作公式,其中k.len是位掩码的长度(在示例中为8)。

实施例中,

k = 01100011
for j = 2 ==> g = 10000000 because k>>(k.len-1-j) is 011
solution is 10000111
--------------------------------
k = 01100011
for j = 4 ==> g = 01101000 because k>>(k.len-1-j) is 01100
solution is 01101001
--------------------------------
k = 01100011
for j = 7 ==> g = 01100100 because k>>(k.len-1-j) is 01100011
solution is 01100101

我想知道这个公式,如果可能的话,可以简单解释一下如何构建公式。

我在http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation找到了 数字k的下一个词典排列的公式,我正在寻找类似的东西。

如果仅使用位运算符而不使用编译器/体系结构相关指令(我使用java),那将会很好,但不是必需的。

1 个答案:

答案 0 :(得分:1)

根据这个问题的答案,这里有一个从C到Java的解决方案:Calculate the smallest integer with k bits set that is greater than another integer x?

public static int smallestIntGreaterOrEqualToXwithKBitsSet(int x, int k)
{
    while (Integer.bitCount(x) > k)
    {
        // Substitute the least-significant group of bits
        // with single bit to the left of them
        x |= x-1;
        ++x;
    }

    for (int i = k - Integer.bitCount(x); i != 0; --i)
    {
        // Set the lowest non-set bit
        x |= x+1;
    }
    return x;
}

我已经改变了#34;大于"到"大于或等于"删除x的第一个增量。

要使用它来解决您的问题,您可以将g的值作为第一个参数传递,将k的bitcount作为第二个参数传递:

public static int nextPerm(int k, int j, int len)
{
    int g = ((k >>(len-1-j))+1)<<(len-1-j);
    return smallestIntGreaterOrEqualToXwithKBitsSet(g, Integer.bitCount(k));
}

测试:

System.out.println(Integer.toBinaryString(nextPerm(0b01100011, 2, 8)));
System.out.println(Integer.toBinaryString(nextPerm(0b01100011, 4, 8)));
System.out.println(Integer.toBinaryString(nextPerm(0b01100011, 7, 8)));

输出:

10000111
1101001
1100101