全排列问题 题解

题目描述
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

输入
输入一个正整数n(n<10)

输出
以字典序给出这n个整数能形成的所有排列,每一行一个排列

示例输入
3

示例输出
123
132
213
231
312
321

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int result[1000000],l=0;//全局变量数组result存储排序结果 
void swap(int &a,int &b)
{
	int temp=a;
	a=b;
	b=temp;
}
void Perm(int num[],int start,int end,int oldstart,int oldend)
{
	if(start==end)//如果问题缩小到只有一个元素,说明一次排列已经完成 
	{
		long long number=0;
		int element=pow(10,oldend-oldstart);
		for(int i=0;i<=end;i++)
		{
			number=number+num[i]*element;
			element=element/10;
		} 
		result[l]=number;
		l=l+1;
	}
	else//继续交换元素位置进行排列 
	{
		for(int i=start;i<=end;i++)//for循环对每一个元素进行与第一个元素的交换 
		{
			swap(num[start],num[i]);
			Perm(num,start+1,end,oldstart,oldend);
			swap(num[start],num[i]);//将交换的元素复原,以进行下一次交换 
		}
	}
}
int main()
{
	int n;
	cin>>n;
	int num[n];
	for(int i=0;i<n;i++)num[i]=i+1;//初始化数组num
	for(int i=0;i<1000000;i++)result[i]=0;//初始化 
	Perm(num,0,n-1,0,n-1);//调用排列函数得到的结果以数字形式存储在result中 
	sort(result,result+l);//排序 
	for(int i=0;i<l;i++)
	cout<<result[i]<<endl;//按照题目要求,排列结果按由小到大顺序打印 
	return 0;
} 

【注意:依照举例,题目要求排列结果从小到大输出】

【如果不用result数组把排列结果按数字形式记录再排序后输出,而是直接在Perm函数的判断start=?end时直接依次输出元素,不能保证从小到大输出】

使用递归,Perm函数对数组num的start和end区段进行递归操作。
输入 3 过程举例:

初始num 1 2 3 start=0,end=2

进入Perm函数

判断start≠end,进入for循环①,逐个交换至数组第一个位置
(对123,1和1交换)num 1 2 3 调用Perm函数 start=1,end=2
判断start≠end,进入for循环②
(对23,2和2交换)num 1 2 3 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字1 2 3
继续循环②

(对23,3和2交换)num 1 3 2 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字1 3 2
循环②一轮结束,交换回去num 1 2 3
循环②结束,继续循环①

(对123,2和1交换)num 2 1 3 调用Perm函数 start=1,end=2
判断start≠end,进入for循环③
(对13,1和1交换)num 2 1 3 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字2 1 3
继续循环③

(对13,3和1交换)num 2 3 1 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字2 3 1
循环③一轮结束,交换回去num 1 2 3
循环③结束,继续循环①

(对123,3和1交换)num 3 2 1 调用Perm函数 start=1,end=2
判断start≠end,进入for循环③
(对21,2和2交换)num 3 2 1 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字3 2 1
继续循环③

(对21,1和2交换)num 3 1 2 调用Perm函数 start=2,end=2
判断start=end,计算此时排列结果为数字3 2 1
循环③一轮结束,交换回去num 1 2 3
循环③结束
循环①结束

对result数组记录的排列结果数字按从打到小排列打印即可。

最终结果:
123
132
213
231
312
321

如有错误,欢迎指出。

猜你喜欢

转载自blog.csdn.net/qq_40315080/article/details/87937373