常数差且按位与零的对数

时间:2019-07-04 17:01:02

标签: bit-manipulation bitmask

如何找到差异为给定常数且按位与为零的对的数量?基本上,所有(x,y)使得 x-y = k;其中k是给定的常数, x&y = 0;

2 个答案:

答案 0 :(得分:1)

一个有趣的问题。

k n-1 ... k 1 k 0 为< em> k 。

l 是最小的 i 的索引,这样 k i = 1
我们可以指出,潜在的一对解决方案 x y 必须的所有位都为 i i 为零。
否则,唯一未设置第 i 位的 xy 的唯一方法是使 x i = y i = 1 x&y 不会设置其 i 位。

现在,我们到达索引 l 处的第一位。
情况更加复杂,因为我们有几种方法可以在 x-y 的结果中设置该位。
为此,我们必须考虑比特集 l..m ,使得 k i = k i + 1 = k i + 2 = ... = 1 l≤i k m = 0

例如,如果 l = 0 m = 1 ,则 k 的两个LSB为01,我们可以通过以下方法获得此结果:计算01-00(1-0)或10-01(2-1)。无论哪种情况,结果都是正确的(1),并且 x y 的位相反,并且在与运算后为零。

当序列由多个序列组成时,必须对每对连续的序列从LSB进行替换。

这里是一个例子。为简化起见,我们假设序列从第0位开始,但是泛化是立即进行的:
k = 0111
平凡的解决方案 x = k = 0111 y = 0 = 0000

在LSB处将1重写为2-1:将1加到x并将1加到y
x = 0111 + 0001 = 1000 = 8 y = 0000 + 0001 = 0001
将索引1处1的位(2 1 )重写为4-2:将x加2并将y加2
x = 0111 + 0010 = 1011 y = 0000 + 0010 = 0010
将索引2(1 2 )处1处的位重写为4 = 8-4:将x加4并将y加4
x = 0111 + 0100 = 1011 y = 0000 + 0100 = 0100

因此,对于由1后跟零的序列:

Compute the trivial solution where x=<sequence> and y=0
for every one in the sequence 
  let i be the position of this one
  generate a new solution by adding 2^i to x and y of the trivial solution

要恢复,必须以两种顺序分解数字,从LSB开始
*零是连续零的序列
*一是一串一,后跟一个零

通过替换获得结果
*零乘一组零
*通过将0、1、2、4、2 i 添加到平凡解01111..11 / 000 ... 000

示例:


k = 22 = 16+4+2 =        0 0 0 1 0 1 1 0  
Rewrite first sequence 
011 -> 011/000 (trivial solution)
       100/001 (trivial solution+1)
       101/010 (trivial solution+2)
Rewrite second sequence
01 ->  01/00   (trivial solution)
       10/01   (trivial solution + 1)

And so there are 3*2=6 solutions
010110/000000  22/0
011000/000010  24/2
011010/000100  26/4
100110/010000  38/16
101000/010010  40/18
101010/010100  42/20

答案 1 :(得分:0)

Java实现就是这样...

import java.util.ArrayList;

public class FindPairs {

    public static void main(String args[]) {
        int arr[] = {1,3,4,5,6,9};
        int k = 3;
        ArrayList<String> out = new ArrayList<String>();

        for(int i=0; i<arr.length; i++) {
            for(int j=i+1; j<arr.length; j++) {
                if((Math.abs(arr[i]-arr[j]) == k) && ((arr[i]&arr[j]) == 0)) {
                    out.add("("+arr[i]+","+arr[j]+")");
                }
            }
        }
        if(out.size()>0) {
            for(String pair:out) {
                System.out.println(pair);
            }
        }else {
            System.out.println("No such pair !");
        }   
    }
}