《Cracking the Coding Interview》——第5章:位操作——题目3

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
", findNext(n));
43     }
44     
45     return 0;
46 }
原文地址:https://www.cnblogs.com/zhuli19901106/p/3610485.html