字符串的排列输出 和组合输出

字符串排列:

[cpp]  view plain copy
  1. #include <iostream>     
  2. #include <algorithm>     
  3. using namespace std;     
  4. template <typename T>     
  5. /* 
  6. 把升序的排列(当然,也可以实现为降序)作为当前排列开始,然后依次计算当前排列的下一个字典序排列。 
  7.  
  8. 对当前排列从后向前扫描,找到一对为升序的相邻元素,记为i和j(i < j)。 
  9. 如果不存在这样一对为升序的相邻元素,则所有排列均已找到,算法结束; 
  10. 否则,重新对当前排列从后向前扫描,找到第一个大于i的元素k,交换i和k 
  11. ,然后对从j开始到结束的子序列反转, 
  12. 则此时得到的新排列就为下一个字典序排列。 
  13. 这种方式实现得到的所有排列是按字典序有序的, 
  14. 这也是C++ STL算法next_permutation的思想。 
  15. 算法实现如下 
  16.  
  17. */  
  18. //字典序  
  19. void CalcAllPermutation(T perm[], int num)//num为排列中元素的个数     
  20. {     
  21.     if (num < 1)     
  22.         return;     
  23.              
  24.     while (true)  
  25.     {     
  26.         int i;     
  27.         for (i = num - 2; i >= 0; --i)  
  28.         {     
  29.             if (perm[i] < perm[i + 1])//从右向左,找到第一对上升的序列    
  30.                 break;     
  31.         }     
  32.              
  33.         if (i < 0)     
  34.             break;  // 已经找到所有排列     
  35.          
  36.         int k;     
  37.         for (k = num - 1; k > i; --k)//从右向左找到第一个比perm[i]大的数  
  38.         {     
  39.             if (perm[k] > perm[i])     
  40.                 break;     
  41.         }     
  42.              
  43.         swap(perm[i], perm[k]);  //交换  
  44.         reverse(perm + i + 1, perm + num);//逆反一下     
  45.              
  46.     }     
  47. }     
  48.     
  49. //递归  
  50. void CalcAllPermutation_R(int perm[], int s, int e)    
  51. {  
  52.     if( s >= e )  
  53.     {  
  54.         //输出  
  55.         return;  
  56.     }  
  57.     for(int i=s;i<=e;i++)  
  58.     {  
  59.       swap(perm[i],perm[s]);  
  60.      CalcAllPermutation_R(perm, s+1,e) ;   
  61.      swap(perm[i],perm[s]);  
  62.     }  
  63.     
  64.   
  65. }  
  66. int main()     
  67. {     
  68.     const int NUM = 12;     
  69.     char perm[NUM];     
  70.          
  71.     for (int i = 0; i < NUM; ++i)     
  72.         perm[i] = 'a' + i;     
  73.          
  74.     CalcAllPermutation(perm, NUM);     
  75. }    


字符串的组合:

[cpp]  view plain copy
  1.  题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。  
  2.   
  3. 本题也可以用递归的思路来求字符串的组合。  
  4.   
  5. 假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。下面是这种思路的参考代码:  
  6.   
  7. void Combination(char* string)  
  8.   
  9. {  
  10.   
  11.     if(string == NULL)  
  12.   
  13.         return;  
  14.   
  15.    
  16.   
  17.     int length = strlen(string);  
  18.   
  19.     vector<char> result;  
  20.   
  21.     for(int i = 1; i <= length; ++ i)  
  22.   
  23.     {  
  24.   
  25.         Combination(string, i, result);  
  26.   
  27.     }  
  28.   
  29. }  
  30.   
  31.    
  32.   
  33. void Combination(char* string, int number, vector<char>& result)  
  34.   
  35. {  
  36.   
  37.     if(number == 0)  
  38.   
  39.     {  
  40.   
  41.         vector<char>::iterator iter = result.begin();  
  42.   
  43.         for(; iter < result.end(); ++ iter)  
  44.   
  45.             printf("%c", *iter);  
  46.   
  47.         printf("\n");  
  48.   
  49.    
  50.   
  51.         return;  
  52.   
  53.     }  
  54.   
  55.    
  56.   
  57.     if(*string == '\0')  
  58.   
  59.         return;  
  60.   
  61.    
  62.   
  63.     result.push_back(*string);  
  64.   
  65.     Combination(string + 1, number - 1, result);  
  66.   
  67.     result.pop_back();  
  68.   
  69.    
  70.   
  71.     Combination(string + 1, number, result);  
  72.   
  73. }  
  74.   
  75.         
  76.   
  77.  由于组合可以是1个字符的组合,2个字符的字符……一直到n个字符的组合,因此在函数void Combination(char* string),我们需要一个for循环。另外,我们一个vector来存放选择放进组合里的字符  
  78.   
  79. 方法二:  
  80. 用一个数组,模拟2进制加法器,某一位为1,则取对应的字符,若为0则不取,就能够实现字符组合。  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值