设f(k)= y其中k是非负整数递增序列中的第y个数 在其二进制表示中与k相同的数量,例如f(0)= 1,f(1)= 1,f(2)= 2,f(3)= 1,f(4) = 3,f(5)= 2,f(6)= 3,依此类推。给定k> = 0,计算f(k)
我们很多人都看过这个问题
这个问题的解决方案是根据1的数量对数字进行分类,然后找到rank.i确实找到了一些模式,但这将是一个漫长的过程。谁能建议我一个更好的解决方案?
答案 0 :(得分:10)
这是一个计数问题。我认为,如果你考虑到这一点,你可以做得比在字面上枚举值并检查它们有多少位更好。
考虑数字17.二进制表示为10001.1的数量为2.我们可以通过两个1来获得较小的数字(在这种情况下)将1重新分配给四个低位中的任何一个。 4选择2是6,所以17应该是第7个数字,其中2个为二进制表示。我们可以检查一下......
0 00000 -
1 00001 -
2 00010 -
3 00011 1
4 00100 -
5 00101 2
6 00110 3
7 00111 -
8 01000 -
9 01001 4
10 01010 5
11 01011 -
12 01100 6
13 01101 -
14 01110 -
15 01111 -
16 10000 -
17 10001 7
我们是对的。概括这个想法,你应该得到一个有效的函数,你只需计算 k的等级。
编辑:提示概括 17的特殊之处在于,如果不考虑高阶位,则数字的等级为1;也就是说,f(z)= 1其中z是除高阶位之外的所有内容。对于不是这种情况的数字,您如何解释在不移动高位的情况下可以获得较小数字的事实?
答案 1 :(得分:4)
f(k)是小于或等于k的整数,其二进制表示中具有与k相同数量的1。
例如,k需要m位,即k = 2^(m-1) + a
,其中a < 2^(m-1)
。与k具有相同位数的小于2^(m-1)
的整数数是choose(m-1, bitcount(k))
,因为您可以在m-1
最低有效位中自由地重新分配这些位。
大于或等于2 ^(m-1)的整数与k具有相同的最高有效位(即1),因此它们有f(k - 2^(m-1))
个。这意味着f(k) = choose(m-1, bitcount(k)) + f(k-2^(m-1))
。
答案 2 :(得分:0)
见"Efficiently Enumerating the Subsets of a Set"。请看表3,“银行家序列”。这是一种精确生成所需序列的方法(如果反转位顺序)。只需用K位运行K迭代。该文件中包含了生成它的代码。