組合

循环法

/***********************//** 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;}

递回法

#include <iostream>#include <cstdio>using namespace std;namespace comb {int n, k;int arr[12];int count;bool arrsame(int site) {
if (site > 0 && arr[site - 1] >= arr[site])
return 0;
return 1;}inline void arrprint() {
for (int i = 0; i < k; i++)
printf("%3d", arr[i]);
puts("");
count++;}void calculate(int now) {
if (now == k) {
arrprint();
return;
}
for (int i = 0; i < n; i++) {
arr[now] = i;
if (arrsame(now)) {
calculate(now + 1);
}
}}inline void run(int nn, int kk) {
n = nn, k = kk;
count = 0;
if (k < 12 && n >= k && k > 0)
calculate(0);
if (count)
printf("\n%d combination.\n\n", count);
else
puts("Input error!");}}int main() {
int n, k;
while (scanf("%d%d", &n, &k) != EOF) {
comb::run(n, k);
fflush(stdout);
}
return 0;}

循环法

/***********************//** This is C++ code. **//**  ReComb  Example  **//***********************/#include <iostream>using namespace std;bool next_re_comb(int* recomb, const int n, const int k) {
int i = k - 1;
do
recomb[i]++;
while (recomb[i] > n - 1 && i--);
if (recomb[0] > n - 1)
return 0;
while (++i < k)
recomb[i] = recomb[i - 1];
return 1;}int main() {
int n, k;
cout << "recomb(n,k):" << endl;
cin >> n >> k;
if (n <= 0 || k <= 0)
return 0;
int* recomb = new int[k];
for (int i = 0; i < k; i++)
recomb[i] = 0;
do
for (int i = 0; i < k; cout << ((++i < k) ? ',' : '\n'))
cout << recomb[i] + 1;
while (next_re_comb(recomb, n, k));
delete[] recomb;
return 0;}

递回法

#include <iostream>#include <cstdio>using namespace std;namespace re_comb {int n, k;int arr[12];int count;bool arrsame(int site) {
if (site > 0 && arr[site - 1] > arr[site])
return 0;
return 1;}inline void arrprint() {
for (int i = 0; i < k; i++)
printf("%3d", arr[i]);
puts("");
count++;}void calculate(int now) {
if (now == k) {
arrprint();
return;
}
for (int i = 0; i < n; i++) {
arr[now] = i;
if (arrsame(now)) {
calculate(now + 1);
}
}}inline void run(int nn, int kk) {
n = nn, k = kk;
count = 0;
if (k < 12 && k > 0)
calculate(0);
if (count)
printf("\n%d combination.\n\n", count);
else
puts("Input error!");}}int main() {
int n, k;
while (scanf("%d%d", &n, &k) != EOF) {
re_comb::run(n, k);
fflush(stdout);
}
return 0;}