这对我来说一直是个挑战。
给定两个表示二进制数的数组,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的确切数量?
答案 0 :(得分:1)
不知道你是否在https://math.stackexchange.com/得到了答案,但让我去试一试。
在下面的所有讨论中,我们只对X
1位的数字感兴趣。我不会一直这么说,为了让它更简单。
因此,我们假设我们可以计算低于给定值A
的数字计数:smaller(A)
。要查找A
和C
之间的数字计数,我们可以将其计算为smaller(C) - smaller(A) - 1
。
让我们定义一个函数,该函数计算在Y位空间{1}中存在多少个X位的数字,例如count(X, Y)
(count(1, 3) = 3
,001
,010
)和100
(count(2, 3) = 3
,011
,101
)。这是标准组合数学,即从袋子中拉出编号为1到Y的X球的组合数。
110
其中count(X, Y) = Y! / ((Y-X)! * X!)
为X!
。
现在我将展示下一部分,如何使用示例计算factorial(X)
。让smaller(A)
。
首先,计算右边的0(2)。然后有A = 010010100
个数字count(1, 2)
以下,其中最右边的1位移到右侧(A
,010010010
)。
提示:使用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之间的数字计数应该不会太糟糕,即使对于高位数也是如此。
无论如何,这是一种方法,但数学方面的天才可能有更好的算法。