找工作,笔试经常会出现一个题,怎样生成一个集合内所有元素的全排列。刚开始的时候没有觉得这是一个难的问题。其实,当写在试卷上,真的不太会,作答的过程感觉心里没有什么底。
回来后,查了一些资料,看了一些书,对这个问题有一定的认识,举一个例去清晰一下题目的意思,例子为:字符集{1,2,3}的全排列:123,132,312,321,231,213。
进一步认识全排列生成:
进一步方法考察:
经过学习与查找,找到如下的算法描述:
觉得这个算法提供一个实现能枚举全部合条件的数据,用C语言进行一个实现:
#include<stdio.h> #define N 4 typedef struct node{ int value ; int flag ; }node; node a[N] ; void init(){ int i ; for(i = 0 ; i < N ; i++){ a[i].value = i + 1 ; a[i].flag = 0 ;//向左指向的 } } void change_flag(int n){ int i ; for(i = 0 ; i < N ; i++){ if(a[i].value > n){ a[i].flag = (a[i].flag == 1) ? 0 : 1 ; } } } void exchange(int x,int y){ int temp ; int f ; temp = a[x].value ; f = a[x].flag ; a[x].value = a[y].value ; a[x].flag = a[y].flag ; a[y].value = temp ; a[y].flag = f ; } int main(){ init() ; int i , j ,max_ind ; int max; int count = 0 ; while(1){ ++count ; for(i = 0 ; i < N ; i++){ printf("%d",a[i].value) ; } printf("\n") ; max_ind = 0 ; max = -1 ; for(i = 0 ; i< N ; i++){//最大的数下标 if(a[i].flag){//向右指 if( i < N-1 && a[i+1].value<a[i].value && max < a[i].value) { max_ind = i ; max = a[i].value ; }//右边的数比较小 } else{//向左指 if( i > 0 && a[i-1].value < a[i].value && max < a[i].value ) { max_ind = i ; max = a[i].value ; }//左边的数比较小 } } if(max == -1){break ;} change_flag(a[max_ind].value) ; if(a[max_ind].flag){//向右指时,与右边的交换 j = max_ind + 1 ; } else{//向左指,与左边的与之交换 j = max_ind - 1 ; } exchange(max_ind,j) ; } printf("sum = %d",count) ; return 0 ; }
看看程序运行结果:
虽然实现了,可是代码一点都不简洁,请各位多多指教。