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

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

#include
#include
int n;
int sum;
void build(int *a,int *top,int m)
{
    if(m==n)
    {
        printf("{");
        for(int i=0;iprintf("%d",a[top[i]]);
        }
        printf("}");
        printf("\n"); 
        return ;
    }
    for(int i=0;im]=i;
        build(a,top,m+1); 
    }
} 

int main()
{
    scanf("%d",&n);
    int *a=(int *)malloc(sizeof(int)*n);
    for(int i=0;i"%d",&a[i]);
    int *top=(int *)malloc(sizeof(int)*n);
    build(a,top,0);
    return 0;
}

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

我们其实可以看到,在生成子集程序中,其算法如下:
C语言算法—(生成子集的升级)生成数据的全部组合(含重复数字)(类似建立树的回溯法)_第1张图片
而我们可以将其改写成这样,就与上面的程序如出一辙了:

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]];

你可能感兴趣的:(C,Algorithm)