組合

在組合數學，一個集的元素的組合（）是一個子集。S的一個k-組合是S的一個有k個元素的子集。若兩個子集的元素完全相同並順序相異，它仍視為同一個組合，這是組合和排列不同之處。

 表示方式 
从 n 个不同元素中取出 k 个元素的所有不同组合的个数，叫做从 n 个不同元素中取出 k 个元素的组合数，记做：、、、（英语）、（法语、罗马尼亚语、俄语、汉语、波兰语）。

理論與公式
从个元素中取出个元素，个元素的组合數量为：

以六合彩為例。在六合彩中从49顆球中取出6顆球的组合數量为：

 在集合中取出k項元素

重複組合理論與公式

从个元素中取出个元素，個元素可以重複出現，這组合數量为：

以取色球為例，每種顏色的球有無限多顆，從8種色球中取出5顆球，好比是在5顆球間畫上分隔號“|”代表球色的分布情形(隔板法)。例如第1種色球取1顆，第2種色球取2顆，第3種色球取2顆可以表示成：
球|球球|球球| | | | |
可以理解为8类球每类取多少个，一起构成5个球。我们把5个球排成一排，用7个分隔线去隔开。如上图，表示含义：第1根线前表示第一类球取的个数，第1根和第2根线表示第二类球取的个数...第6第7根线前表示第七类球的个数，第7根后表示第八类球的个数。亦即問題是從(5+8-1)個位置中挑選出(8-1)個位置擺分隔號，這組合數量為：

因為組合數量公式特性，重複組合轉換成組合有另一種公式為：

另外也可以記為 OCLC:44527392或

 取值範圍的擴充
在的定義中，由於它有意義的範圍必須是滿足條件，所以其他範圍必須另外定義，我們有:

 演算範例 
 組合 C 
 迴圈法 
/***********************/
/** This is C++ code. **/
/**   Comb  Example   **/
/***********************/

#include <iostream>
#include <vector>
using namespace std;

bool next_comb(vector<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 false;
    while (++i < k)
        comb[i] = comb[i - 1] + 1;
    return true;
}

int main() {
    int n, k;
    cout << "comb(n, k):" << endl;
    cin >> n >> k;

    if (n < k || k <= 0) {
        cout << "Invalid input: n must be >= k and k must be > 0." << endl;
        return 0;
    }

    vector<int> comb(k);
    for (int i = 0; i < k; i++)
        comb[i] = i;

    do {
        for (int i = 0; i < k; i++) {
            cout << comb[i] + 1;
            if (i < k - 1) cout << ',';
        }
        cout << endl;
    } while (next_comb(comb, n, k));

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

 重複組合 H 

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

 推广 

组合数可以推广到多分类的情形  ，我们将n个物品分为m份，每份的个数分别为:个，那么，总的分类数为

 参见 

 概率论
 组合数学

 參考文獻 

 外部链接 
  组合数公式的直观理解及其推广 

Category:组合数学