题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
解析:我通过位数组来实现打印所有组合,这类似于用字符串模拟加法操作一样。不过用字符串模拟加法操作是逢10进1,用位模拟是逢2进1。以abc为例:
初始化位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中的一个数;
然后设置下一位;
递归结束条件:已经设置了数字的最后一位