《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\n", findNext(n));

43     }

44     

45     return 0;

46 }

 

你可能感兴趣的:(interview)