蓝桥杯 - 下一个排列 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 )。
代码在此:
先看看网上是怎么介绍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; }
相关文章推荐
- 排列算法的C语言实现
- 排列和组合的非递归算法的C语言实现
- 【C语言】编写一个函数reverse_string(char * string)(递归实现),将参数字符串中的字符反向排列,不能使用C函数库中的字符串操作函数。
- c语言实现排列组合算法问题
- c语言实现二维数组排序,一个4*5的数组,要求每行都进行升序排列,并求出每行的平均值。
- C语言实现排列/组合算法
- C语言:编写reverse_string(char * string)(递归实现)函数,将参数字符串中的字符反向排列
- C语言 编写一个函数reverse_string(char * string) 实现:将参数字符串中的字符反向排列。
- C语言 编写一个函数reverse_string(char * string) 实现:将参数字符串中的字符反向排列。 要求:不能使用C函数库中的字符串操作函数。
- C语言—— 将N个数按输入时顺序的逆序排列,用函数实现
- 全排列---递归实现与分析(C语言)
- C语言实现排列组合
- c语言实现排列组合算法问题
- 【c语言】编写一个函数reverse_string(char * string)(递归实现) 实现:将参数字符串中的字符反向排列。
- C语言实现 函数reverse_string(char * string) 将参数字符串中的字符反向排列。
- C语言实现数学上的组合和排列
- 排列与组合的C语言实现
- C语言实现输入一个字符串后打印出该字符串中字符的所有排列
- C语言:将n个数输入时的顺序逆序排列,用函数实现。
- C语言实现的阶乘,排列和组合实例