C 递归:从一个袋子里挑8个球。问题:如何避免相同的答案?

C 递归:从一个袋子里挑8个球。问题:如何避免相同的答案?,c,recursion,C,Recursion,我陷入了一个递归问题。 问题:一个袋子里有3个红球、3个白球和6个黑球。需要从袋子里拿8个球。有多少种组合,它们是什么 我已经用C实现了这个问题,但问题是我不知道如何从我的答案中去掉完全相同的解决方案。实际答案是13种组合,我已经使用UNIX的“uniq”操作符验证了这一点。然而,我想得到一些帮助,如何从我的程序中删除相同的组合 非常感谢!!!多谢各位 // 3R 3W 6B, pick 8, how many possible combination #include <stdio.h

我陷入了一个递归问题。 问题:一个袋子里有3个红球、3个白球和6个黑球。需要从袋子里拿8个球。有多少种组合,它们是什么

我已经用C实现了这个问题,但问题是我不知道如何从我的答案中去掉完全相同的解决方案。实际答案是13种组合,我已经使用UNIX的“uniq”操作符验证了这一点。然而,我想得到一些帮助,如何从我的程序中删除相同的组合

非常感谢!!!多谢各位

// 3R 3W 6B, pick 8, how many possible combination

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void func(int r, int w, int b, int total);


int main(void){
    printf("The result is\n");
    func(3, 3, 6, 0);
    return 0;
}


void func(int r, int w, int b, int total){
    if (r < 0 || w < 0 || b < 0){
        return;
    }
    else if (total >= 8){
        printf("R = %d, W = %d, B = %d\n", 3-r, 3-w, 6-b);
        return;
    }
    else{
        func(r-1, w, b, total+1);
        func(r, w-1, b, total+1);
        func(r, w, b-1, total+1);

        return;
    }
}
/3R 3W 6B,选择8,有多少种可能的组合
#包括
#包括
#包括
无效函数(整数r、整数w、整数b、整数总计);
内部主(空){
printf(“结果是\n”);
func(3,3,6,0);
返回0;
}
无效函数(整数r、整数w、整数b、整数总计){
if(r<0 | | w<0 | | b<0){
返回;
}
否则,如果(总数>=8){
printf(“R=%d,W=%d,B=%d\n”,3-R,3-W,6-B);
返回;
}
否则{
func(r-1,w,b,总计+1);
func(r,w-1,b,总计+1);
func(r、w、b-1,总计+1);
返回;
}
}

每次从每种颜色中取出一个球,你可以在不同的路径上得到相同的答案。例如,先拿一个红色的球,然后拿一个白色的球,得出的计数与先拿一个白色的球,然后拿一个红色的球得出的计数相同。在代码中,每个递归级别对应一个单独的球,如果球的顺序很重要,那么这是一种很好的方法

您可以以不同的方式订购:

  • 考虑所有选择红球的可能性(0、1、2或3)
    • 考虑所有的方法,以采取白色球(0至3再次)
      • 考虑所有的方法去拿黑球(0到6)
        • 如果我们有8个球,打印解决方案

(这个解决方案不是最优的:它将以一种野蛮的方式考虑所有的可能性。它可以通过不减少可能性而被优化,这取决于已经采取了多少球。这里的关键点是看重新排序你的递归解决问题。) <>你可以把这个代码硬编码到你的程序中,但是让我们来考虑一个更一般的解决方案,你可以指定每个数组中的每个球的可用数量和总数。

此解决方案也是递归的,但这里的每个递归级别对应于球的颜色:

int take(int *ball,     // array of available balls of each colour
         int *taken,    // record of balls taken from each colour
         int n,         // size of ball and taken arrays
         int i,         // currently considered colour
         int total)     // balls taken, counting down from intended number
{
    int res = 0;
    int j;

    if (i < n) {
        // consider nexz colour

        for (j = 0; j < ball[i] + 1; j++) {
            taken[i] = j;

            res += take(ball, taken, n, i + 1, total - j);
        }
    } else {
        // all colours have been considered

        if (total == 0) {
            for (j = 0; j < n; j++) {
                if (j) printf(", ");
                printf("%d", taken[j]);
            }

            puts("");

            res = 1;
        }
    }

    return res;
}
int main(void)
{
    int ball[] = {3, 3, 6};     // red, white and black balls
    int taken[3];               // will be filled in by "take"

    int res = take(ball, taken, 3, 0, 8);

    printf("(%d possibilities)\n", res);

    return 0;
}