(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 ;}
- (1)字符串全排列 / 组合
- 字符串的组合排列(非全排列)
- 字符串的全排列和全组合
- 字符串的全排列_全组合
- 字符串全组合与全排列
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- [收集]字符串的全排列和组合
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 字符串全排列和组合算法
- 字符串的全排列和组合算法
- 字符串的全排列和组合算法
- 黑马程序员_网络编程
- 各种排序算法稳定性的总结
- 入侵oracle数据库时常用的操作命令整理
- #pragma pack()
- UVa 11100 The Trip, 2007 (贪心&一举两得的输出技巧)
- (1)字符串全排列 / 组合
- 手机界面布局
- 详解Big-Endian和Little-Endian,大端模式和小端模式
- systemui statusbar service 小结
- C++宏定义错误
- 游戏嵌入 文字广告"欢迎使用**组系列游戏,**组网站致力打造国内最大最全资源分享平台!"
- Oracle 10g 下载地址
- HTML 常用标记
- errno.h错误码列表