下一次全排列结果
上一篇文章我写的全排列的方法,那么如果给定一组排列好的数字,例如“12453”,那么下一次按照一般思路做下一次排列将会得到什么样的结果呢?
我们知道,接照一般思路来说,一组数“123456”,下一次我们会将6和5作交换,即得“123465”,接着再对倒数第三个数进行操做,将5和6中较小的数,即5放到倒数第三个位置上,再把4和6按升序排列,即得“123546”。
按照这个方法我们就能得到“12453”的下一次排列结果。
A. 定义一个变量nDropPos来保存第一个降序数的下标, 同时定义另一个变量n_pos保存从右到左的第一个比降序数大的下标
B. 判断降序数位置及大小,若降序数下标为-1,则不作处理。
若降序数出现在倒数第二个位置,则交换两个数。若降序数大于nDropPos-2,则交换降序数与nDropPos-1下标的数。
否则将该降序数与n_pos下标的数交换,并从nDropPos+2下标开始一直到strlen(s) -1结束,进行除序排序。代码如下所示:
#include <iostream>
#include <string.h>
using namespace std;
#define exchange(x, y) {int temp = x; x = y; y = temp;}
const int N = 8;
int index[N] = {0, 1, 2, 3, 4, 5, 6, 7};//排列数
void sort(int *p, int beg, int end)
{//冒泡排序
int i = 0;
for(; end > beg; end --)
for(i = beg; i < end; i++)
if(*(p + i) > *(p + i + 1))
exchange(*(p + i), *(p + i + 1));
}
void print()
{//打印结果
int i = 0;
for(i = 0; i < N; i++)
cout << index[i] << " ";
cout << endl;
}
void next_permutation(int* cur, int n)
{//得到下一次全排列
int i = 0, decIndex = n- 1, excIndex = n - 1, temp = 0;
if(cur[n - 1] > cur[n - 2])
{
exchange(cur[n - 1], cur[n - 2]);
print();
return;
}
for(i = n - 1; i > -1; i --)
{
if(*(cur + i) > *(cur + i - 1))
{
decIndex = i - 1;//得到第一个降序数
break;
}
}
if(decIndex == -1)
return;
temp = cur[decIndex];
for(i = decIndex + 1; i < n; i++)
{//得到要交换的数
if(cur[i] > temp)
temp = cur[i];
if(cur[i] > cur[decIndex] && cur[i] <= temp)
excIndex = i;
}
exchange(cur[decIndex], cur[excIndex]);
sort(cur, decIndex + 1, n - 1);
print();
}
int main()
{
int n = 0, resu = 0;
for(n = 0; n < 24; n++)//循环做下一次全排列
next_permutation(index, 4);//index为当前排列,4为要排列的元素个数
system("pause");
return 0;
}