问题:
给N个正整数,给出这N个数字所有不同的排列,即全排列,按字典序输出。
输入格式:
输入在第一行中给出一个整数N (1<N<10)。接下来一行给出N个数字,按递增(非递减)序排列。
输出格式:
输出所有排列,每个排列一行,数字间用空格分开,末尾的数字后面无空格。
输入样例1:
3
1 1 2
输出样例1:
1 1 2
1 2 1
2 1 1
输入样例2:
5
9 9 9 9 9
输出样例2:
9 9 9 9 9
解法:
如何找一堆数的下一个字典序输出:
1.从右往左找的第一个满足右边数大于左边数的两个数,将右边数命名为R,左边数命名为L。
2.从R开始(包括R)寻找R右边满足大于L并且最小的一个数,命名为S。
3.将L与S交换位置。
4.将R右边(包括R)进行递增排列。
由于这里本来就是按递增顺序给出的数组,如果没有,一开始应该将数组变成递增形式。
代码:
#include <iostream>
#include<string>
#include <stdlib.h>
using namespace std;
void arr_up(int* p ,int n)//用于对数组某个元素之后的元素进行升序排列
{
int temp;
for (int i = n; i > 1; i--)
{
for (int j = 0; j < i-1; j++)
{
if (p[j + 1] < p[j])
{
temp = p[j + 1];
p[j + 1] = p[j];
p[j] = temp;
}
}
}
}
bool dictionary(int* a, int n)//返回值为bool,用于判断是否有下一个字典序排列
{
int* p = NULL;
int temp;
for (int i = n - 1; i > 0; i--)
{
if (a[i] > a[i - 1])//步骤1
{
//满足步骤1,就进入步骤2到4
p = &a[i];
for (int j = i; j <= n - 1; j++)
{
if (a[j]<*p && a[j]>a[i - 1])
{
p = &a[j];
}
}
temp = *p;
*p = a[i - 1];
a[i - 1] = temp;
arr_up(&a[i], n - i);
break;
}
}
if (p == NULL)//表示没有进入步骤1,整个数组按递减输出,没有下一个字典序排列
{
return false;
}
return true;
}
int main()
{
int N;
cin >> N;
int* arr = new int[N];
for (int i = 0;i < N; i++)
{
cin >> arr[i];
}
for (int i = 0; i < N; i++)
{
if (i != 0)
cout << " ";
cout << arr[i];
}
cout << endl;
while (dictionary(arr, N))
{
for (int i = 0; i < N; i++)
{
if (i != 0)
cout << " ";
cout << arr[i];
}
cout << endl;
}
}
842

被折叠的 条评论
为什么被折叠?



