字典序(自己实现next_permutation)

问题:输入n,从小到大输出从1到n,n个数的字典序

步骤:

1.初始化,将1~n从小到大存入buf数组

2.n个数的全排列有n!个,则调用n!次,并输出字典序。

3.my_next_permutation实现:

  1. 从后往前遍历buf数组,每次比较buf[i],buf[i+1],找到第一个正序序列,记下此时的下标a=i;
  2. 从a开始往后遍历,找到后n-a-1个数中大于buf[a]且最小的数,记下其下标b
  3. 调换buf[a],buf[b]
  4. 数组元素从a+1到n逆序

下面是代码实现:

#include <iostream>
#include <cstdio>

using namespace std;


int factorial(int n) {//计算阶乘
	int result = 1;
	for (int i = 2; i <= n; i++) {
		result *= i;
	}
	return result;
}

void my_next_permutation(int *buf,int n) {//计算字典序
	int a;
	for(int i=n-2; i>=0; i--) {//从后往前遍历,找到a
		if(buf[i]<buf[i+1]) {
			a=i;
			break;
		}
	}
	int b;
	int min1=10;
	for(int i=a; i<n; i++) {//从a向后遍历,找到符合要求的b
		if(buf[i]>buf[a]&&buf[i]<min1) {
			b=i;
			min1=buf[i];
		}
	}
	int temp=buf[a];//换位
	buf[a]=buf[b];
	buf[b]=temp;
	for(int i=a+1; i<=(a+n-1)/2; i++) {//逆序
		temp=buf[i];
		buf[i]=buf[a+n-i];
		buf[a+n-i]=temp;
	}
}

int buf[10];


int main() {
	int n;
	cin>>n;
	for(int i=0; i<n; i++) {
		buf[i]=i+1;
	}
	for(int i=0; i<factorial(n); i++) {//n!次调用
		for(int j=0; j<n; j++) {//输出
			if(j==0)cout<<buf[j];
			else cout<<' '<<buf[j];
		}
		cout<<endl;
		my_next_permutation(buf,n);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/BrightHao_zi/article/details/87378729