2014-03-19 05:57
题目:给定一个整数N,求出比N大,而且二进制表示中和N有相同个数的‘1’的最小的数,比如3是‘11’,接下来的5是‘101’,再接下来的6是‘110’。
解法:从低位往高位,首先跳过连续的‘0’,然后跳过连续的‘1’,并数数有多少个1。如果这时还没到最高位,那就从刚才跳过的‘1’中拿出1个放到这位上(当前位是‘0’),然后把剩下的‘1’填到最低的几位上去。中间填充‘0’。比如:‘100111000’的下一个是‘101000011’
代码:
1 // 5.3 Find the next largest number that have same number of '1's with the given number. 2 #include <cstdio> 3 using namespace std; 4 5 unsigned int findNext(unsigned int n) 6 { 7 int n_zero; 8 int n_one; 9 10 n_zero = 0; 11 while (n_zero < 32 && (n & (1 << n_zero)) == 0) { 12 ++n_zero; 13 } 14 if (n_zero == 32) { 15 // all 0 16 return n; 17 } 18 19 n_one = n_zero; 20 while (n_one < 32 && (n & (1 << n_one)) != 0) { 21 ++n_one; 22 } 23 if (n_one == 32) { 24 // no larger number is possible 25 return n; 26 } 27 28 n = n >> n_one << n_one; 29 n |= (1 << n_one); 30 for (int i = 0; i < n_one - n_zero - 1; ++i) { 31 n |= (1 << i); 32 } 33 34 return n; 35 } 36 37 int main() 38 { 39 unsigned int n; 40 41 while (scanf("%u", &n) == 1) { 42 printf("%u\n", findNext(n)); 43 } 44 45 return 0; 46 }