(1)字符串全排列 / 组合

来源:互联网 发布:mysql表空间查看 编辑:程序博客网 时间:2024/06/06 07:50

题目描述:输入一个字符串,打印出该字符串的全部排列;

例如:字符串:abc     全排列:(abc , acb) , (bac , bca) , (cba , cab);

解题思路:

递归实现:从字符串中“依次”选择一个字符作为“首字符”,并在该“首字符”前提下,对剩余字符进行递归全排列处理;


“依次”:即始终在“初始字符串”的前提下,后面的字符分别于第一个字符交换;

字符串abc:

(abc)首字符a-->求剩余bc全排列:abc , acb;-->(a,b)交换-->bac;

(bac)首字符b-->求剩余ac全排列:bac , bca;-->(a,b)交换-->abc(以便在此基础上得到cba)-->(a,c)交换-->cba;

(cba)首字符c-->求剩余ba全排列:cba,cab;


算法递归实现:

#include<iostream>using namespace std;//------------------------------------------------------------------------------------------------------------------void  Permutation(char* pStr , char* pBegin);void  Swap(char *ch1 , char *ch2);//-------------------------------------------------------------------------------------------------------------------void  Swap(char *ch1 , char *ch2){char temp = *ch1;*ch1 = *ch2;*ch2 = temp;}//不能保证出现重复排列。void Permutation(char* pStr , char* pBegin){if(*pBegin == '\0'){printf("%s\n" , pStr);}elsefor(char* pch = pBegin; *pch != '\0'; ++pch){                        Swap(pch , pBegin); Permutation(pStr , pBegin + 1);Swap(pch , pBegin);}}void Permutation(char* pStr){if(pStr == NULL)return ;Permutation(pStr , pStr);}

但是若字符串中出现重复的字符,两者交换。全排列中会出现重复的结果。这样不仅加大工作量,而且还是没有意义的,故应该去掉重复的全排列结果。

怎么去除呢?

规则:从首字符起,每个字符依次与后面不重复的字符交换。

例子:字符串abb;

(abb)首字符a-->求剩余全排列:abb-->(b,b)相等不交换;-->(a,b)交换bab;

(bab)首字符b-->求剩余全排列:bab , bba;-->(b,a)交换abb-->由于二三字符b ,b 相同,故a不再与第三个字符交换,结束;

代码实现:

#include<iostream>  using namespace std;  //------------------------------------------------------------------------------------------------------------------------bool IsSwap(char* pBegin , char* pEnd);           //判断是否有字符相等void Permutation(char* pStr , char *pBegin);//------------------------------------------------------------------------------------------------------------------------void Permutation(char* pStr){if(!pStr)return;Permutation(pStr , pStr);}  //在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等  bool IsSwaped(char* pBegin , char* pEnd)  {      char *S;      for(S = pBegin ; S < pEnd ; S++)      {          if(*S == *pEnd)              return false;      }      return true;  }  void Permutation(char* pStr , char *pBegin)  {        if(*pBegin == '\0')      {          printf("%s\n",pStr);      }      else      {    //依次与首字符交换,固定。剩余递归进行全排列        for(char *pCh = pBegin; *pCh != '\0'; pCh++)          {              if(IsSwaped(pBegin , pCh))              {                  swap(*pBegin , *pCh);                  Permutation(pStr , pBegin + 1);                  swap(*pBegin , *pCh);              }          }      }  }  


字符串的组合问题:

问题描述:给定一个字符串,求该字符串中所有字符的组合;例如abc,所求组合为:a , b , c , ab , ac , bc , abc;


长度为n的字符串,选取m个字符的组合,其中1 <= m <= n;

设总组合数为Comb(n , m) = Comb(n , 1) + Comb(n , 2) + Comb(n , 3) + ......+ Comb(n , n);

递归求解

从首字符开始扫描,若被选中,则递归求解:Comb(n - 1 , m - 1);

                                 若未被选中,则递归求解:Comb(n - 1 , m);

递归终止条件: n = 0  或者  m = 0;


代码实现:

#include<iostream>#include<vector>#include<cstring>using namespace std;//------------------------------------------------------------------------------------------------------------------void Combination(char* pStr , int m , vector<char>& result);//-------------------------------------------------------------------------------------------------------------------//函数功能:求一个字符串的所有组合//参数:字符串pStrvoid Combination(char* pStr){if(pStr == NULL)return;vector<char> result;      int length = strlen(pStr);for(int i = 1; i <= length; i++)Combination(pStr , i , result);}//函数功能:从一个字符串中选取m个字符//参数:字符串pStr ,选取元素个数m , 存放结果resultvoid Combination(char* pStr , int m , vector<char>& result){if(pStr == NULL || (*pStr == '\0' && m != 0))return;//递归终止条件if(m == 0){vector<char>::iterator  iter = result.begin();for( ; iter != result.end(); iter++)cout<<*iter<<' ';cout<<endl;return;     //注意}//选中此元素result.push_back(*pStr);Combination(pStr + 1 , m - 1 , result);result.pop_back();//未选中此元素Combination(pStr + 1 , m , result);}//----------------------------------------------------------------------------------------------------------------int main(){char string1 [] = " ";      Combination(string1);char string2[] = "accd";Combination(string2);return 0 ;}