全排列(next_permutation)算法

功能: 给定一个具有n个元素的集合,要求输出这个集合中元素的全部可能的排列。

STL有一个函数next_permutation(),它的作用是假设对于一个序列,存在依照字典排序后这个排列的下一个排列,那么就返回true且产生这个排列,否则返回false。
注意,为了产生全排列,这个序列要是有序的,也就是说要调用一次sort。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
      int ans[4]={1,2,3,4};
      sort(ans,ans+4);    /* 这个sort可以不用,因为{1,2,3,4}已经排好序*/
      do                             /*注意这步,如果是while循环,则需要提前输出*/
      {
        for(int i=0;i<4;++i)//循环输出ans[i]
             cout<<ans[i]<<" ";
             cout<<endl;
     }while(next_permutation(ans,ans+4));
    return 0;
}
image.png

手写全排列:

#include <iostream>
using namespace std;

void f(int x[], int k,int m)//全排列 数组x长度为k--m
{
    int i,t;
    if(k>=m){//输出所有情况 
        for(i=0;i<m;i++){
        printf("%d",x[i]);  
    }
        printf("\n");
    }
    
    for(i=k; i<m; i++){ //递归穷举所有可能情况 
        {t=x[k]; x[k]=x[i]; x[i]=t;}
        f(x,k+1,m);
        {t=x[k]; x[k]=x[i]; x[i]=t;}
    }
}
    
int main()
{
    int x[] = {1,2,3};
    f(x,0,3);    
    return 0;

}

例题:

五、九数组分数

1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法?

下面的程序实现了该功能,请填写划线部分缺失的代码。

#include <stdio.h>

void test(int x[])
{
    int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];//分子 
    int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];//分母 
    
    if(a*3==b) printf("%d / %d\n", a, b);//组成分数为三分之一 
}

void f(int x[], int k)//全排列 
{
    int i,t;
    if(k>=9){
        test(x);
        return;
    }
    
    for(i=k; i<9; i++){
        {t=x[k]; x[k]=x[i]; x[i]=t;}
        f(x,k+1);
        _____________________________________________ // 填空处
    }
}
    
int main()
{
    int x[] = {1,2,3,4,5,6,7,8,9};
    f(x,0);    
    return 0;
}

注意:只填写缺少的内容,不要书写任何题面已有代码或说明性文字。

分析:f(x,k+1)回溯之后,将交换后的结果还原使用回朔法。

答案:{t=x[k]; x[k]=x[i]; x[i]=t;}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容