字符串的组合

来源:互联网 发布:linux exec shell 编辑:程序博客网 时间:2024/06/05 19:50

问题:

输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。

分析:

以前做过类似的题目,求解字符串所有的排列,采用的递归思路。

二进制方法

这个题我想到的第一种方式是考虑到2^n的特殊性,如果字符串长度为5,我们可以有2^5中组合方式,则用二进制表示,第i位为1,表示输出string[i];如果为0,则不输出。

算法如下:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <math.h>using namespace std;int main(){char *string = "abcdef";int len = strlen(string);if(len > 32)return -1;int number = (int)pow(2.0, len);for(int i = 0 ; i < number; i++){for(int j = 0; j < len; j++){if((i>>j) & 1)//判断是否为1,为1就输出string对应的第i位cout << string[j];}cout << endl;}return 0;}
递归方法

和排列一样,采用递归的思路,计算string的组合时,考虑string[0]是否保存到结果,这样进行两次递归,一次包含stirng[0],另一种不包含string[0],这里我们需要使用一个栈,用于保存结果。注意维护栈的状态,这是关键点,和排列类似。

算法:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <vector>using namespace std;void combination(char *string, int len, vector<char> &result){if(len == 0){vector<char>::iterator itr = result.begin();for(;itr < result.end(); itr++){printf("%c", *itr);}printf("\n");return ;}//第一种,不包含string[0]result.push_back(string[0]);combination(string + 1, len - 1, result);result.pop_back();//注意要弹出,恢复到开始状态,不然会出现错误//第二种,包含string[0]combination(string + 1, len - 1, result);return ;}int main(){char *string = "abcdef";vector<char> result;combination(string, strlen(string), result);return 0;}

总结:

第一种采用二进制的方式,受到整数长度的限制,int只能表示32个字符的表示;第二种方式,采用递归的思路,维护一个栈,用于保存结果,这种方式比较直观易懂,推荐第二种方法。