【问题标题】:Why is this not generating all possible subsets?为什么这不能生成所有可能的子集?
【发布时间】:2019-09-12 03:02:24
【问题描述】:

我正在尝试生成给定集合的所有可能子集。但是,该程序生成的子集少于所有可能的子集。例如,如果 Candidate[] = 1, 2, 3, 4, 5 仅打印 25 个子集。 我错过了什么? 另外,关于如何对每个子集中的每个元素求和并检查总和是否等于特定数字的任何想法? 例如,检查 1、2、3 的哪些子集的元素总和为 3。(输出应为 {1、2} 和 {3})

我尝试修改了一些条件,但没有任何效果。

#include <stdio.h>
#include <stdlib.h>
#include "sum.h"
void combinations(int, int, int);

int main()
{
    int i;
    printf("The combinations are:\n");
    for (i = 1; i <= candidatessize; i++)
        combinations(0, 0, i);
}

void combinations(int start, int index, int num_sub)
{
    int i, j;
    if (index - start + 1  ==  num_sub)
    {
        if (num_sub  ==  1)
        {
            for (i = 0; i < candidatessize; i++)
                printf("%u\n", candidates[i]);
        }
        else
        {
            for (j = index; j < candidatessize; j++)
            {
                for (i = start; i < index; i++)
                    printf("%u ", candidates[i]);
                printf("%u\n", candidates[j]);
            }
            if (start != candidatessize - num_sub)
                combinations(start+1, index+1, num_sub);
        }
    }
    else
    {
        combinations(start, index + 1, num_sub);
    }
}

(候选数组和大小在标题中声明)

如果候选人[] = 1, 2, 3, 4, 5 该程序应打印 31 个子集

【问题讨论】:

  • 这看起来像是一个家庭作业问题。它有几个问题。目前还不清楚 start 和 index 代表什么。你还有一个候选数组——这是输入数组吗?如果它不是并且是一个用于保存子集元素的数组,那么您需要在递归所有组合时添加/替换其中的元素。你的递归逻辑也不清楚。
  • 目前还不清楚这个程序应该如何工作。由于您使用的是递归,因此您似乎有某种方法可以根据较小集合的子集来描述集合 S 的子集。你能用英文写下你的描述吗?
  • 想想你如何计算子集的数量:2^n。 IE。对于 n 个候选者中的每一个,您决定它是否在子集中(2 个可能性,n 次,因此 2^n)。你的代码需要做类似的事情。

标签: c recursion combinations permutation


【解决方案1】:

数字要么显示 (1),要么不显示 (0)。 要查找所有 31 个(即 2^5 -1),您可以使用 5 位数字 这恰好映射到要显示的元素数量。 像这样:

/*
arr[5] = {  5,    4,    3,    2,    1   };     
            0     0     0     0     0 
            0     0     0     0     1
            0     0     0     1     0 
            0     0     0     1     1
            ...
            1     1     1     1     1
*/

#include <stdio.h>



int main()
{
    int arr[5] = {1,2,3,4,5};
    unsigned char x = 1;

    for (; x < 32; x++)                              // run from 2^0 to 2^5 - 1
    {
        if (x & 0x01) printf("%d ", arr[0]);         // extract 2^0 bit     
        if ((x & 0x02) >> 1) printf("%d ", arr[1]);  // extract 2^1 bit
        if ((x & 0x04) >> 2) printf("%d ", arr[2]);  // extract 2^2 bit
        if ((x & 0x08) >> 3) printf("%d ", arr[3]);  // extract 2^3 bit
        if ((x & 0x10) >> 4) printf("%d ", arr[4]);  // extract 2^4 bit
        printf("\n");
    }


    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 2013-08-11
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多