功能: 给定一个具有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;}
网友评论