C语言算法—(生成子集的升级)生成数据的全部组合(含重复数字)(类似建立树的回溯法)

来源:互联网 发布:压缩相片软件下载 编辑:程序博客网 时间:2024/05/18 15:27

继上篇文章(生成子集)之后,我们来看类似于此种算法的另一种功能算法:生成固定数据的全部组合;
先上算法:

#include<stdio.h>#include<malloc.h>int n;int sum;void build(int *a,int *top,int m){    if(m==n)    {        printf("{");        for(int i=0;i<n;++i)        {            printf("%d",a[top[i]]);        }        printf("}");        printf("\n");         return ;    }    for(int i=0;i<n;++i)    {        top[m]=i;        build(a,top,m+1);     }} int main(){    scanf("%d",&n);    int *a=(int *)malloc(sizeof(int)*n);    for(int i=0;i<n;++i)    scanf("%d",&a[i]);    int *top=(int *)malloc(sizeof(int)*n);    build(a,top,0);    return 0;}

我们可以看到,这个算法和生成子集算法的唯一不同只在于赋值top数组的不同而已;

我们其实可以看到,在生成子集程序中,其算法如下:
程序
而我们可以将其改写成这样,就与上面的程序如出一辙了:

for(int i=0;i<2;++i){     top[n]=i;     build(a,tag,n+1);}

其寓意不过是,将top所代表的值的选择,在生成子集中,每一位只有显示或不显示两种选择,但在自由组合中,每一位都有n中组合;例如,在1,2,3中,每一位都有三种选择,为1,2,3,而在a中对应的则是0-2;所以在top记录数组中,每一位都可以赋值为0-2中的任意值;

而在输出中,我们可以看到的是,top数组指定的是这一位显示a数组中的哪一位,例如top[0]中显示的是1,则意味着第一个输出的数,是a数组中1号元素对应的数,若a[3]={1,2,3},则第一个元素应输出2,而不是1;

这就是为什么在输出中的形式应该是:a[top[i]];

0 0