你可以使用来自hackersdelight.org的讨厌的黑客攻击.
在他的书中,他有代码来获得具有相同数量的一位集的下一个更高的数字.
如果你使用它作为基元来增加你的数量,你所要做的就是找到一个起点.获得N位设置的第一个数字很容易.它只是2 ^(N-1)-1.
您将以这种方式非常快速地遍历所有可能的数字.
unsigned next_set_of_n_elements(unsigned x) { unsigned smallest, ripple, new_smallest, ones; if (x == 0) return 0; smallest = (x & -x); ripple = x + smallest; new_smallest = (ripple & -ripple); ones = ((new_smallest/smallest) >> 1) - 1; return ripple | ones; } // test code (shown for two-bit digits) void test (void) { int bits = 2; int a = pow(2,bits) - 1; int i; for (i=0; i<100; i++) { printf ("next number is %d\n", a); a = next_set_of_n_elements(a); } }
Jon Skeet.. 14
尝试从相反的方向接近问题 - 你要做的就是"找到0-31范围内的n个数字".
假设您正在尝试查找4个数字.你从[0,1,2,3]开始,然后每次增加最后一个数字(得到[0,1,2,4],[0,1,2,5] ......)直到达到极限[0,1,2,31].然后增加倒数第二个数字,并将最后一个数字设置为更高:[0,1,3,4].回去增加最后一个数字:[0,1,3,5],[0,1,3,6] ......等.一旦你到了这个结尾,你会回到[0,1,4] ,5] - 最终你达到[0,1,30,31],此时你必须进一步向后退一步:[0,2,3,4]然后再离开你.继续,直到你最终[28,29,30,31].
给定一组数字,将它们转换为32位数字显然很容易.
你可以使用来自hackersdelight.org的讨厌的黑客攻击.
在他的书中,他有代码来获得具有相同数量的一位集的下一个更高的数字.
如果你使用它作为基元来增加你的数量,你所要做的就是找到一个起点.获得N位设置的第一个数字很容易.它只是2 ^(N-1)-1.
您将以这种方式非常快速地遍历所有可能的数字.
unsigned next_set_of_n_elements(unsigned x) { unsigned smallest, ripple, new_smallest, ones; if (x == 0) return 0; smallest = (x & -x); ripple = x + smallest; new_smallest = (ripple & -ripple); ones = ((new_smallest/smallest) >> 1) - 1; return ripple | ones; } // test code (shown for two-bit digits) void test (void) { int bits = 2; int a = pow(2,bits) - 1; int i; for (i=0; i<100; i++) { printf ("next number is %d\n", a); a = next_set_of_n_elements(a); } }
尝试从相反的方向接近问题 - 你要做的就是"找到0-31范围内的n个数字".
假设您正在尝试查找4个数字.你从[0,1,2,3]开始,然后每次增加最后一个数字(得到[0,1,2,4],[0,1,2,5] ......)直到达到极限[0,1,2,31].然后增加倒数第二个数字,并将最后一个数字设置为更高:[0,1,3,4].回去增加最后一个数字:[0,1,3,5],[0,1,3,6] ......等.一旦你到了这个结尾,你会回到[0,1,4] ,5] - 最终你达到[0,1,30,31],此时你必须进一步向后退一步:[0,2,3,4]然后再离开你.继续,直到你最终[28,29,30,31].
给定一组数字,将它们转换为32位数字显然很容易.