位运算模拟二进制加法--位图方法

题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有abcabacbcabc

解析:我通过位数组来实现打印所有组合,这类似于用字符串模拟加法操作一样。不过用字符串模拟加法操作是逢101,用位模拟是逢21abc为例:

初始化位bitset<3>模拟每次加1它的变化为为000---001 ---010 -- 011 --- 100 ---101 --- 110--111 。当某一位为 0的时候,不输出,为 1的时候输出对应于 abc中的那一位。

01.#include <iostream>  

02.#include <bitset>  

03.#include <string>  

04.using std::cout; 

05.using std::cin; 

06.using std::endl; 

07.using std::string; 

08.using std::bitset; 

09. 

10.// 由于c++中bitset不支持动态分配。使用bitset<n>时 n的值不能使用局部变量  

11.// 所以现在只能是用全局变量计算出字符的个数,再赋值给n。 当STR改变时,不要  

12.// 忘了手动改变CHAR_COUNT 的值  

13.const string STR = "abc";  

14.const int CHAR_COUNT = 3; // 字符的个数  

15. 

16.bool Increment(bitset<CHAR_COUNT>&bits) 

17.{ 

18.   if(CHAR_COUNT <= 0) 

19.       return false; 

20.   for(int i = CHAR_COUNT-1; i >=0; i--) 

21.   { 

22.       if(0 == bits[i]) 

23.       { 

24.            bits[i] = 1; 

25.            break; 

26.       } 

27.       else  

28.       { 

29.            if(i != 0)  

30.            { 

31.                bits[i] = 0; // 相当于进位操作,低位置为0  

32.            } 

33.            else 

34.            { 

35.                return false; // 最高位为1 ,再次进行加法将溢出  

36.            } 

37.       } 

38.   } 

39.   return true; 

40.} 

41.void Print(const bitset<CHAR_COUNT>&bits,const string&str) 

42.{ 

43.   if(CHAR_COUNT <= 0 || CHAR_COUNT != str.length()) 

44.   { 

45.       return; 

46.   } 

47.   for(int i = 0; i != CHAR_COUNT; i++) 

48.   { 

49.       if(1 == bits[i]) 

50.            cout << str[i]; 

51.   } 

52.   cout << endl; 

53.} 

54. 

55.void Combination() 

56.{ 

57.   bitset<CHAR_COUNT> bits; 

58.   while(Increment(bits)) 

59.   { 

60.       Print(bits, STR); 

61.   } 

62.} 

63.int main() 

64.{ 

65.   Combination();  

66.   system("pause"); 

67.}

运行实例:

000

100

010

110

001

101

011

111

相关题目:《剑指off》    

打印1到最大的n位数

方法1:从1开始逐个打印

方法2:字符串模拟数字加法

字符串表示数字

字符串的每个字符从‘0’~‘9’,因为数字最大是n位,所以需要n+1位的字符串(最后一个是结束符‘\0’)

算法:

1,字符串的每一个数字初始化为‘0’

2,每次为字符串表示的数字加1,打印出来

  

模拟加1

判断是否停止加1

方法1:使用strcmp比较字符串和最大的n为数“999...999”;

      判断是否到了最大的n位数的时间复杂度:O(1)

方法2:更佳

只有对“999...99”加1时,才会在第1个字符(下标为0)的基础上产生进位,

其他情况不会产生进位;

所以,当发现加1时第一个字符产生进位时,则已经是最大的n位数,此时

increment返回true

 

判断是否到了最大的n位数的时间复杂度:O(1)

    

打印字符串

关键:

只有碰到第一个非0的字符后才开始打印

 

附加:此题还可以使用递归求解【详见《剑指offer》面试题12】

思路:

n位所有十进制其实就是n个从0到9的全排列

即,我们把数字的每一位都从0到9排列一遍,就是所有的十进制。只是打印时,数字排在前面的0不打印出来。

全排列递归:

数字的每一位都可能是0~9中的一个数;

然后设置下一位;

递归结束条件:已经设置了数字的最后一位

   



  





     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值