计算具有相同属性

时间:2017-04-12 03:54:57

标签: java binary combinatorics

这对我来说一直是个挑战。

给定两个表示二进制数的数组,A和C具有相同的大小,由数字0或1表示的比特组成,使得C> 1。 A,并且两者具有相同的X比特1比特,计算存在多少二进制数B的最有效方式是什么,使得A <1。 B&lt; C,并且每个B也有X个1位?

示例:对于A = {0,1,0,0,1} C = {1,0,1,0,0} X = 2
所有B都是{0,1,0,1,0},{0,1,1,0,0},{1,0,0,0,1},{1,0,0,1,0 },这将给我答案4.在01001和10100之间有4个2'1'位的二进制文件。

我有一个算法来生成给定A的下一个B,但我觉得继续生成下一个B并且检查我是否已经击中C二进制文件并不高效。

有没有办法在不生成B的情况下计算A和C之间B的确切数量?

1 个答案:

答案 0 :(得分:1)

不知道你是否在https://math.stackexchange.com/得到了答案,但让我去试一试。

在下面的所有讨论中,我们只对X 1位的数字感兴趣。我不会一直这么说,为了让它更简单。

因此,我们假设我们可以计算低于给定值A的数字计数:smaller(A)。要查找AC之间的数字计数,我们可以将其计算为smaller(C) - smaller(A) - 1

让我们定义一个函数,该函数计算在Y位空间{1}中存在多少个X位的数字,例如count(X, Y)count(1, 3) = 3001010)和100count(2, 3) = 3011101)。这是标准组合数学,即从袋子中拉出编号为1到Y的X球的组合数。

110

其中count(X, Y) = Y! / ((Y-X)! * X!) X!

现在我将展示下一部分,如何使用示例计算factorial(X)。让smaller(A)

首先,计算右边的0(2)。然后有A = 010010100个数字count(1, 2)以下,其中最右边的1位移到右侧(A010010010)。

提示:使用count = Integer.numberOfTrailingZeros(A)

删除该1位,留下010010001

提示:使用A = 010010000

重复,即计数0(4),但这次我们需要计算2位组合,即A = A ^ (1 << count)

离开count(2, 4),这会导致A = 010000000

因此,因为1位位于第2,4和7位,我们可以计算:

count(3, 7)

现在,通过smaller(A) = count(1, 2) + count(2, 4) + count(3, 7) 的高效实现,计算A和C之间的数字计数应该不会太糟糕,即使对于高位数也是如此。

无论如何,这是一种方法,但数学方面的天才可能有更好的算法。