1. 程式人生 > >利用字典序生成下一個排列和組合的方法

利用字典序生成下一個排列和組合的方法

先介紹生成排列的方法最簡單的方法是用STL自帶的next_permutation() 引數為要生成下一個排列的區間
int n, p[10];
	cin >> n;
	for (int i = 0; i < n; i++) cin >> p[i];
	sort(p, p + n);
	do {
		for (int i = 0; i < n; i++) cout << p[i];
		cout << endl;
	} while (next_permutation(p, p + n)); //若已經是最後一個排列則返回false
這個函式還可以接受比較函式,預設是小於號
利用字典序方法(其實上面這個函式就是用這個方法生成下一個排列的)先說下方法吧,以排列P1,P2,P3...Pn為例1 先從又右向左找到第一個滿足Pi-1<Pi的i2 再從右向左找第一個比Pi-1大的數,假設是Pk3 交換Pi-1與Pk,重新排列pi-1之後的數(不包含Pi-1)
int n, p[10];
	cin >> n;
	for (int i = 0; i < n; i++) cin >> p[i];
	sort(p, p + n);
	while (1)
	{
		for (int i = 0; i < n; i++)
			cout << p[i];
		cout << endl;
		int i = n - 1;
		while (i > 0 && p[i - 1] > p[i]) i--;
		if (i == 0) break; //i==0說明已經是最後一個排列
		int j;
		for (j = n - 1; j >= i; j--) if (p[j] > p[i - 1]) break;
		swap(p[i - 1], p[j]);
		sort(p + i, p + n);
	}
生成排列數這兩種方法就足夠了,建議使用第一種,簡單好用對於如何生成集合S={1,2...n)的r組合,直接參考部落格程式碼連結下面介紹如何生成集合S={1,2...n)的所有子集

節省時間,並沒有講述原理,想了解的可以百度

1
void print_subset(int n, int *A, int cur) {   //增量構造法 
	for (int i = 0; i < cur; i++) cout << A[i] + 1;   //輸出
	puts("");
	int s = cur ? A[cur - 1] + 1 : 0;              //確定當前元素最小可能值
	for (int i = s; i < n; i++) {              
		A[cur] = i;
		print_subset(n, A, cur + 1);                 //遞迴構造子集
	}
		
}
int main()
{
	int n, a[10]; cin >> n;                  //n是集合元素的個數
	print_subset(n, a, 0);              
	system("pause");
}
2
void print_subset(int n, int *A, int cur) {   //位向量法
	if (cur == n) {
		for (int i = 0; i < cur; i++)
			if (A[i]) printf("%d", i + 1);
		puts(""); return;
	}
	A[cur] = 1;
	print_subset(n, A, cur + 1);
	A[cur] = 0;
	print_subset(n, A, cur + 1);	
}
int main()
{
	int n, a[10]; cin >> n;                  //n是集合元素的個數
	print_subset(n, a, 0);              
	system("pause");
}
3 (最簡練)
void print_subset(int n, int s) {   //二進位制法
	for (int i = 0; i < n; i++)
		if (s&(1 << i)) printf("%d", i + 1);
	printf("\n");
}
int main()
{
	int n, a[10]; cin >> n;                  //n是集合元素的個數
	for (int i = 1; i < (1 << n); i++)
		print_subset(n, i);
	system("pause");
}