您的位置:首页 > 编程语言 > C语言/C++

蓝桥杯 - 下一个排列 C语言实现

2017-03-31 16:00 190 查看
下一个排列

先看看网上是怎么介绍next_permutation函数:

next_permutation函数在 组合数学中经常用到排列,这里介绍一个计算序列全排列的函数:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn<pm<pn+1.

分析:
在做一道“困难的串”的算法题时候发现c语言没有类似c++ next_permutation函数可以调用, 网上找了一下关于c语言写next_permutation函数也比较乱,于是自己写了一下。

对于一个序列(数字,如果要换成字母就65 +或 97 +并用%c输出)从倒序寻找数字当A
>A[n-1]时,然后再寻找A
(包括A
)到最后面的最小值min。将min与A[n-1]交换。余下的数字(指的是A
到最后面的数,包括A
)按从小到大排序即可。

比如:1 5 4 3 2 ,这序列计算下来A[n-1](1),则A
(5)后面的最小min(2)(注意这个最小的数要大于A[n-1]至于为什么就想一下)。将min(2)与A[n-1](1)交换。剩下的A[n-1](交换后变成2)后面排序得
2 (1 3 4 5 )。

代码在此:
#include<stdio.h>

void swap (int *a, int *b) {	//交换函数
int temp;
temp = *a;
*a = *b;
*b = temp;
}

void sort (int a[], int st, int fi) {	//自己写的选择排序替代c++ sort();当然肯定没c++的sort()效率高 ;对a[]数组的下标st到下标fi的排序
int i, j, k, temp;
int n = fi + 1;
for(i = st; i < n-1; i ++){
k = i;
for(j = i+1; j < n; j ++){
if(a[k] > a[j])
k = j;
}
if(k != i){
temp = a[k];
a[k] = a[i];
a[i] = temp;
}
}
}

int Next_Permutation (int A[], int n) {

int i;
int num;	//待交换的数的下标

for(i = n - 2; i >= 0; i --){	//计算出A[n-1] <
的情况,A[n-1]待交换数中的n-1就是num
if (A[i+1] > A[i])
break;
}
if(i < 0)	//说明数列已经是降序数列 如 3 2 1 没有 3 位的后续排列
return 0;

num = i;	//待交换的数

i = i + 1;	//i做为 A
的下标
int min = i;	//先默认 A
为最小数
i ++;	// i++寻找A[n-1]右边更小的数
for(; i < n; i ++){
if(A[i] < A[min] && A[i] >= A[num]){	// && A[i] >= A[num]这个条件必须加,因为这是个定序推导,不然你去掉试一试
min = i;
}
}

swap(A + num, A + min);	//交换
sort(A, num + 1, n - 1);	// A[n-1]之后的重排

return 1;
}

int main () {

int i;
int n;
//	int a[] = {65, 66, 67, 68};	//大写之母
int a[] = {1, 2, 3, };
n = 3;

for(i = 0; i < n; i ++)
printf("%d ", a[i]);
printf("\n");
while(Next_Permutation(a, n)){
for(i = 0; i < n; i ++)
printf("%d ", a[i]);
printf("\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐