-
字符串的排列组合问题:http://blog.csdn.net/wuzhekai1985/article/details/6643127
-
之前一直没有实现过,今天理解一下
#include <iostream> #include <iterator> using namespace std; //输出数组全排列 //算法思路: //(1)n个元素的全排列 = (n - 1个元素的全排列) + (另一个元素作为前缀); //(2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组; //(3)不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组; void perm(int list[], int k, int m) { if (k == m) { copy(list, list + m, ostream_iterator<int>(cout, " ")); cout << endl; return; } for (int i = k; i < m; i++)//第一次自己和自己换 { swap(list[k], list[i]); perm(list, k + 1, m); swap(list[k], list[i]); } } int main() { int List[] = { 1, 2, 3 }; perm(List, 0, sizeof(List) / sizeof(int)); return 0; }
- 参考
1.全排列:用递归的思想求出全排列 #include "stdafx.h" #include <iostream> using namespace std; void swap(int &a,int &b)//交换连个元素 { int tem; tem = a; a = b; b = tem; } void cal(int *a,int first,int length) { if(first == length)//如果递归到深层时,到最后交换的元素即时最后一个元素时就打印出来 { for(int i = 0; i <= length; i++) cout<<a[i]<<" "; cout<<endl; } else { for(int i = first; i <= length; i++) {//循环遍历使得当前位置后边的每一个元素都和当前深度的第一个元素交换一次 swap(a[first],a[i]);//使得与第一个元素交换 cal(a,first+1,length);//深入递归,此时已确定前边的元素,处理后边子序列的全排列形式。 swap(a[first],a[i]);//恢复交换之前的状态 } } } int main() { int a[6] = {1,2,3,4,5,6}; cal(a,0,5); return 0; } 2.借助于上面的求出全排列的方法,求组合的时候只是在递归到低时输出的不一样,这里只输出组合个数的元素: #include "stdafx.h" #include <iostream> using namespace std; void swap(int &a,int &b)//交换连个元素 { int tem; tem = a; a = b; b = tem; } void cal(int *a,int first,int length,int r) { if(first == length)//如果递归到深层时,到最后交换的元素即时最后一个元素时就打印出来 { for(int i = 0; i <= r; i++) cout<<a[i]<<" "; //bug 错误的:如果12345;则n(5,2):(12345,12435,12354...等输出前面的都是一样的) cout<<endl; } else { for(int i = first; i <= length; i++) {//循环遍历使得当前位置后边的每一个元素都和当前深度的第一个元素交换一次 swap(a[first],a[i]);//使得与第一个元素交换 cal(a,first+1,length,r);//深入递归,此时已确定前边的元素,处理后边子序列的全排列形式。 swap(a[first],a[i]);//恢复交换之前的状态 } } } int main() { int a[6] = {1,2,3}; cal(a,0,2,1); return 0; }