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

 
 

先介绍生成排列的方法
最简单的方法是用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的i
2 再从右向左找第一个比Pi-1大的数,假设是Pk
3 交换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");
}





猜你喜欢

转载自blog.csdn.net/qq_41776911/article/details/80188458