全排列:
设待排列的数组为a[n],任意时刻将其分为0~s-1和s~n-1两端。
其中,0~s-1是已经选择的区间,s~n-1是待选择的区间,每次选择s~n-1的一个与s为的数交换
#include <iostream>
using namespace std;
void swap(int *a, int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
//0~s-1, s~n-1
void perm(int *a, int s, int n)
{
if(s >= n)
{
for(int i = 0; i < n; i++)
{
cout << a[i] << ",";
}
cout << endl;
}
else
{
for(int i = s; i < n; i++)
{
swap(a, s, i);
perm(a, s+1, n);
swap(a, s, i);
}
}
}
int main()
{
int n;
cin >> n;
int a[100];
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
perm(a, 0, n);
return 0;
}
从大小为n的数组a[n]中找到所有大小为m的组合
递归函数 comp(int *a, int h, int k, int *sub) 表示在数组a的前h个数中选择k个,因为要保证下一次递归时可以选择k-1个,所以本次选择的范围是a[i], 其中k-1<= i <= h-1,并将a[i]复制给已选集sub[k-1],
并进行下一次递归 comp(a, i, k-1, sub) 表示在数组a的前i个数中选择k-1个
#include <iostream>
using namespace std;
int n;
int m;
int num = 0;
void comb(int *a, int h, int k, int *sub)
{
if(k == 0)
{
for(int i = 0; i < m; i++)
{
cout << sub[i] << ",";
}
cout << endl;
num ++;
}
else
{
for(int i = h-1; i >= k-1; i--)
{
sub[k-1] = a[i];
comb(a, i, k-1, sub);
}
}
}
int main()
{
int n;
cin >> n >> m;
int a[100], sub[100];
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
comb(a, n, m, sub);
cout << num << endl;
return 0;
}