title:
一、输入一个字符串,打印出字符串中字符的所有排列
二、打印出字符串中字符的所有组合(如ab和ba是两种排列但是只能算一种组合)
thought:
一:
1、将一个字符串分为两部分:第一部分为第一个字符,之后的子串属于第二部分;
2、将第一个字符依次与后面的字符交换;
3、每交换一次,对新串的第二部分子串进行递归的1、2操作;
4、操作完之后,要把交换的两个字符恢复原位:这样做是为了避免出现重复的排序;
5、到达字符串的最末位截止。
二:n是字符串的长度,m是从字符串中选取的字符个数(m=1,2,...n)
1、处理字符*str时,有两种方式:
选中此字符,接着处理下一字符*(str+1),然后m变成m-1;
不选此字符,接着处理下一字符*(str+1),但是m保持不变(因为没选*str,所以仍然需要从剩余字符中选取m个);
2、对每个m进行上述处理,m取值从1到n,所以需要调用n次步骤1。
一、输入一个字符串,打印出字符串中字符的所有排列
二、打印出字符串中字符的所有组合(如ab和ba是两种排列但是只能算一种组合)
thought:
一:
1、将一个字符串分为两部分:第一部分为第一个字符,之后的子串属于第二部分;
2、将第一个字符依次与后面的字符交换;
3、每交换一次,对新串的第二部分子串进行递归的1、2操作;
4、操作完之后,要把交换的两个字符恢复原位:这样做是为了避免出现重复的排序;
5、到达字符串的最末位截止。
二:n是字符串的长度,m是从字符串中选取的字符个数(m=1,2,...n)
1、处理字符*str时,有两种方式:
选中此字符,接着处理下一字符*(str+1),然后m变成m-1;
不选此字符,接着处理下一字符*(str+1),但是m保持不变(因为没选*str,所以仍然需要从剩余字符中选取m个);
2、对每个m进行上述处理,m取值从1到n,所以需要调用n次步骤1。
注:当n==0 or m== 0时,实现一种组合。
<pre name="code" class="cpp">#include<iostream>
#include<vector>
using namespace std;
static int cnt_permunation = 0; //统计全排列的个数
static int cnt_combine = 0; //统计字符的组合数
void string_permunation(char *str);
void permunation(char *str,char *str_begin);//str始终指向完整字符串的首字符,str_begin指向当前处理的字符串的首字符
void str_Combine(char *str);
void Combine_recurise(char *str,int m,vector<char> &result);
void string_permunation(char *str)
{
if(NULL == str)
return;
permunation(str,str);
}
void permunation(char *str,char *str_begin) //str_begin指向当前处理的子串
{
if(*str_begin == '\0') //第五步:到达字符串的最末位截止,并输出当前排列
{
cout << str << endl;
cnt_permunation++;
}
else
{
for(char *str_current = str_begin;*str_current !='\0';str_current++)
{
char temp_before = *str_begin;
*str_begin = *str_current;
*str_current = temp_before; //第一、二步:当前子串的首位与后面的字符交换
permunation(str,str_begin+1); // 第三步:交换之后,对新串的子串(str_begin+1)进行全排列(递归)
char temp_after = *str_begin;
*str_begin = *str_current;
*str_current = temp_after; //第四步:递归全排列之后,把之前交换的两个字符恢复原位
}
}
}
void str_Combine(char *str)
{
if(NULL == str || *str == '\0')
return;
int length = strlen(str);
for (int i = 0; i < length; i++)
{
vector<char> result;
Combine_recurise(str,i,result);
}
}
void Combine_recurise(char *str,int m,vector<char> &result)
{
if(NULL == str || (*str == '\0' && m != 0))
return ;
if(m == 0) //m==0时,完成一种组合
{
cnt_combine++;
for(int i = 0;i < result.size();i++)
cout << result[i];
cout<< endl;
return ;
}
result.push_back(*str); //步骤1:选择此字符,m-1
Combine_recurise(str+1,m-1,result);
result.pop_back(); //将选择的字符弹出(变成不选此字符的情况)
Combine_recurise(str+1,m,result); //步骤1:不选此字符,m不变
}
int main()
{
char str[]="abcd";
cout << str <<"的全排列如下:"<< endl;
string_permunation(str);
cout << "共" <<cnt_permunation << "个全排列" << endl;
cout << str << "的组合如下:" <<endl;
str_Combine(str);
cout << "共" <<cnt_combine << "个组合" << endl;
return 0;
}