4

我试图找出给定数字是否是给定集合的总和,例如:数字12是集合的总和s{3,2},因为:

3+3+3+3=12
or
2+2+2+2+2+2=12

14不是总和,s{8,10}因为您无法14使用sums of s. 我正在尝试仅使用递归而不使用循环在 java 中编写代码。这是代码:

   public static boolean isSumOf(int[]s,int n)
   {
     return isSumOf(s,n,0,0,0);
   }


   private static boolean isSumOf(int[]s,int n,int i,int sum,int m)
   {
       boolean with=false;
       boolean without=false;

       if(i==s.length)
        return false;

       if(sum==n)   
        return true;

       if(m<=n)
        {
            with=isSumOf(s,n,i,sum+s[i]*m,m++);
            without=isSumOf(s,n,i,sum,m++);            
        }
       else
        {
            i=i++;
            m=0;
            isSumOf(s,n,i,sum,m);
        }

       return (with||without); 

   }

代码编译正常,但是当我对其进行测试时出现 stackOverFlowError 。这是测试的代码:

  public static void main(String[]args)
  {  
      int[]a={18,10,6};
      int x=18+10+6;
      System.out.println(Ex14.isSumOf(a,x));
  }

请帮忙!!!

4

3 回答 3

2

这看起来很糟糕:

with=isSumOf(s,n,i,sum+s[i]*m,m++);
without=isSumOf(s,n,i,sum,m++);

利用

with=isSumOf(s,n,i,sum+s[i]*m,++m);
without=isSumOf(s,n,i,sum,++m);

如果你想m在被调用的方法中有一个更高的值。

除此之外,由于变量命名不佳,我不知道代码做了什么。

还有这一行:

i=i++;

没有效果,如果要增加,请用以下之一替换它i

i++;
i += 1;
i = i + 1;
i = ++i;

如果你不使用调用的结果

isSumOf(s,n,i,sum,m); 

调用它是没有意义的。

于 2012-11-30T09:02:43.467 回答
0

这似乎有效 - 我没有看到任何迹象表明您不想要现成的答案(我相信如果这是家庭作业,您会说明)所以这里是:

public class IsSumOf {
  // set - The numbers allowed.
  // total - The number I want to achieve.
  // i - Where we are in the set.
  // sum - List of numbers used so far.
  // n - The number we just subtracted (or 0 if none).
  // Note that sum and n are only used for the printing of the route.
  private static boolean isSumOf(int[] set, int total, int i, LinkedList<Integer> sum, int n) {
    // Found the set if we are now at 0.
    boolean is = (total == 0);
    // Look no further if no more to try.
    if ( total > 0 ) {
      // Look no further if we've exhausted the array.
      if ( i < set.length ) {
        // Try or consume this number in the set (or not) and try again.
        is = isSumOf(set, total - set[i], i, sum, set[i] ) 
                || isSumOf(set, total - set[i], i+1, sum, set[i] ) 
                || isSumOf(set, total, i+1, sum, 0 ) ;
      }
    }
    // Keep track of the route.
    if ( is && sum != null && n != 0) {
      // Add backwards so we get the order right when printed.
      sum.addFirst(n);
    }
    return is;
  }

  // Jump-off point.
  public static boolean isSumOf(int[] set, int total, LinkedList<Integer> sum) {
    // Empty the list.
    sum.clear();
    // Start at 0 in the array.
    return isSumOf(set, total, 0, sum, 0);
  }

  public static void main(String[] args) {
    LinkedList<Integer> sum = new LinkedList<Integer>();
    int[] a = {18, 10, 6};
    int x = 18 + 10 + 6;
    System.out.println(Arrays.toString(a)+" ("+x+") = "+(isSumOf(a, x, sum)?Arrays.toString(sum.toArray()):"-"));
    x += 1;
    System.out.println(Arrays.toString(a)+" ("+x+") = "+(isSumOf(a, x, sum)?Arrays.toString(sum.toArray()):"-"));
    int[] b = {3,2};
    x = 12;
    System.out.println(Arrays.toString(b)+" ("+x+") = "+(isSumOf(b, x, sum)?Arrays.toString(sum.toArray()):"-"));
    x += 1;
    System.out.println(Arrays.toString(b)+" ("+x+") = "+(isSumOf(b, x, sum)?Arrays.toString(sum.toArray()):"-"));
    int[] c = {2,3};
    x = 12;
    System.out.println(Arrays.toString(c)+" ("+x+") = "+(isSumOf(c, x, sum)?Arrays.toString(sum.toArray()):"-"));
    x += 1;
    System.out.println(Arrays.toString(c)+" ("+x+") = "+(isSumOf(c, x, sum)?Arrays.toString(sum.toArray()):"-"));
  }
}

编辑打印所走的路线。

印刷:

[18, 10, 6] (34) = [18, 10, 6]
[18, 10, 6] (35) = -
[3, 2] (12) = [3, 3, 3, 3]
[3, 2] (13) = [3, 3, 3, 2, 2]
[2, 3] (12) = [2, 2, 2, 2, 2, 2]
[2, 3] (13) = [2, 2, 2, 2, 2, 3]
于 2012-11-30T10:13:32.933 回答
0

我会使用稍微不同的策略

public static void main(String[] args)
{
    int[] s = { 4, 5 };
    System.out.println(isSumOf(s, 13)); // true
    System.out.println();

    int[] s1 = { 4, 9, 3 };
    System.out.println(isSumOf(s1, 15)); // true
    System.out.println();

    int[] s2 = { 4, 9, 3 };
    System.out.println(isSumOf(s2, 5)); // false
    System.out.println();

    int[] s3 = { 3, 2 };
    System.out.println(isSumOf(s3, 12)); // true
    System.out.println();

    int[] s4 = { 8, 10 };
    System.out.println(isSumOf(s4, 14)); // false
    System.out.println();
}

public static boolean isSumOf(int[] s, int n)
{
    return isSumOf(s, n, 0, 0, "");
}

private static boolean isSumOf(int[] s, int n, int i, int sum, String builder)
{
    if (sum == n) // if we found a subset
    {
        System.out.println(builder);
        return true;
    }

    if (i == s.length || sum > n) // 1. boundaries checks 2. if subset is greater then n
        return false;

    boolean with = isSumOf(s, n, i, sum + s[i], builder + s[i] + " "); // try to sum "s[i]", note that we can sum the
                                                                        // same "s[i]" multiple times

    boolean without = isSumOf(s, n, i + 1, sum, builder); // try to skip "s[i]" and instead to sum "s[i+1]"

    return with || without;
}
于 2021-05-05T16:33:39.537 回答