排列组合问题是高中数学知识,但是在现实中非常需要;对于计算机编程领域来说更是数不胜数。
一、排列问题
排列(英语:Permutation)是将相异对象或符号根据确定的顺序重排,每个顺序都称作一个排列。
1.1排列数的计数
此节使用排列的传统定义。从 n个相异元素中取出 {\displaystyle k} k个元素, k个元素的排列数量为:
1.2重复排列问题
从n个元素中取出k个元素,k个元素可以重复出现,这排列数量为:
1.3C++实现
#include <iostream>
using namespace std;
bool arrsame(int* arr, int len, int num) {
int i;
for (i = 0; i < len; i++)
if (arr[i] == num)
break;
return i != len;
}
bool next_perm(int* perm, const int k, const int n) {
int i = k - 1;
do
perm[i]++;
while (arrsame(perm, i, perm[i]) || (perm[i] >= n && i--));
if (perm[0] >= n)
return 0;
for (int num = 0, seat = i + 1; seat < k; num++)
if (!arrsame(perm, i + 1, num))
perm[seat++] = num;
return 1;
}
int main() {
int n, k;
cout << "perm(n,k):" << endl;
cin >> n >> k;
if (n < k || k <= 0)
return 0;
int* perm = new int[k];
for (int i = 0; i < k; i++)
perm[i] = i;
do
for (int i = 0; i < k; cout << ((++i < k) ? ',' : '\n'))
cout << perm[i] + 1;
while (next_perm(perm, k, n));
delete[] perm;
return 0;
}
二、组合问题
在组合数学,一个集的元素的组合(英语:Combination)是一个子集。S的一个k-组合是S的一个有k个元素的子集。若两个子集的元素完全相同并顺序相异,它仍视为同一个组合,这是组合和排列不同之处。
2.1理论公式计算
从 n个元素中取出 k个元素, k个元素的组合数量为:
2.2取值范围的扩充
2.3C++ 实现
//循环法实现
/***********************/
/** This is C++ code. **/
/** Comb Example **/
/***********************/
#include <iostream>
using namespace std;
bool next_comb(int* comb, const int n, const int k) {
int i = k - 1;
const int e = n - k;
do
comb[i]++;
while (comb[i] > e + i && i--);
if (comb[0] > e)
return 0;
while (++i < k)
comb[i] = comb[i - 1] + 1;
return 1;
}
int main() {
int n, k;
cout << "comb(n,k):" << endl;
cin >> n >> k;
if (n < k || k <= 0)
return 0;
int* comb = new int[k];
for (int i = 0; i < k; i++)
comb[i] = i;
do
for (int i = 0; i < k; cout << ((++i < k) ? ',' : '\n'))
cout << comb[i] + 1;
while (next_comb(comb, n, k));
delete[] comb;
return 0;
}