C - 递归地查找没有循环的子集和

时间:2014-03-06 16:09:28

标签: c recursion subset

我希望得到一些帮助。我在c中有这个代码,用于查找是否存在大小为set[]的数组n的子集,其总计为sum

示例:

 set[] = {1,2,3};
 n = 2;
 sum = 4;

上面的代码将返回true,因为size-2子集{1,3} = 4 它也是如此:

n = 3;
sum = 6;

但是假的:

n = 1; 
sum = 4;

它适用于某些情况,但驱动程序中的情况不会在此代码中为驱动程序正确返回。请注意,我无法更改参数,不想使用任何类型的循环

,代码在这里:

#include <stdio.h>

bool isSubsetSum(int set[], int n, int sum)
{
    // Base Cases
    if (sum == 0)
        return true;
    if (n == 0 && sum != 0)
        return false;

    if (set[n-1] > sum)
        return isSubsetSum(set, n-1, sum);

    return isSubsetSum(set, n-1, sum) || isSubsetSum(set, n-1, sum-set[n-1]);
}

// Driver program to test above function
int main()
{
    int set[] = {6,5,6};
    int sum = 12;
    int n = 2;
    if (isSubsetSum(set, n, sum) == true)
        printf("Found a subset with given sum");
    else
        printf("No subset with given sum");
    return 0;
}

JAVA改编:(也是错误)n是子集的大小

 public static boolean isSubsetSum(int[] set, int n, int sum) {
    int[] copy = new int[set.length - 1];
    System.arraycopy(set, 0, copy, 0, set.length - 1);

    // Base Cases
      if (sum == 0 && n == 0)
        return true;
      if (set.length == 0)       // fixed base case. 
        return false;

      if (set[set.length - 1] > sum) {
        return isSubsetSum(copy, n, sum);
      }

      return isSubsetSum(copy, n, sum) || isSubsetSum(copy, n-1, sum - set[set.length-1]);
}

3 个答案:

答案 0 :(得分:0)

您会混淆集合的大小和子集的大小。让n设计整套的大小,并设置k子集的大小。然后:

#include <stdio.h>
bool isSubsetSum(int set[], int n, int k, int sum)
{
  // Base Cases
  if (sum == 0 && k == 0)
    return true;
  if (n == 0)       // fixed base case. 
    return false;

  if (set[n-1] > sum)
    return isSubsetSum(set, n-1, k, sum);

  return isSubsetSum(set, n-1, k, sum) || isSubsetSum(set, n-1, k-1, sum-set[n-1]);
}

int main()
{
  int set[] = {6,5,6};
  int sum = 12;
  int n = 3;
  int k = 2;
  if (isSubsetSum(set, n, k, sum))
    printf("Found a subset with given sum\n");
  else
    printf("No subset with given sum\n");
  return 0;
}

答案 1 :(得分:0)

您还需要将set的大小作为参数传递。以下代码有效。

#include <stdio.h>

bool isSubsetSum(int set[], int m,int n, int sum)
{

 if (n == 0 && sum == 0)
 return true;
 if(m==0)
    return false;

if (set[m-1] > sum)
 return isSubsetSum(set, m-1,n, sum);

return isSubsetSum(set, m-1,n, sum) || isSubsetSum(set, m-1,n-1, sum-set[m-1]);
}

// Driver program to test above function
int main()
{
 int set[] = {6,5,6};
 int sum = 13;
 int n = 2;
 if (isSubsetSum(set, 3,n, sum) == true)
 printf("Found a subset with given sum");
else
 printf("No subset with given sum");
return 0;
}

答案 2 :(得分:0)

使用列表末尾的0表示设置的长度。

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

bool isSubsetSum(int set[], int n, int sum) {
  if (n == 0)
    return sum == 0;
  if (set[0] == 0)  // End of the line
    return false;
  if (isSubsetSum(set + 1, n, sum)) // Do not use first element
    return true;
  if (isSubsetSum(set + 1, n - 1, sum - set[0])) // Use first element
    return true;
  return false;
}

// Driver program to test above function
int main() {
  int set[] = { 6, 5, 6, 0 };
  int sum = 12;
  int n = 2;
  if (isSubsetSum(set, n, sum) == true)
    printf("Found a subset with given sum");
  else
    printf("No subset with given sum");
  return 0;
}

这也适用于负数。