首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对给定目标的5的倍数之和

对给定目标的5的倍数之和
EN

Stack Overflow用户
提问于 2011-05-13 04:13:36
回答 1查看 950关注 0票数 3

可能重复:

Java : Summation of multiples of 5 in a group to a given target

大家好,

我正在努力让下面的问题在没有正确方向的情况下解决。

编写一个java函数,以便给定一个in数组,是否可以选择一个由某些in组成的组,以便该组与给定目标的总和具有以下附加约束:数组中所有5的倍数都必须包含在组中。如果紧跟在倍数5后面的值是1,则不能选择它。

(0,{2,5,10,4},19)

  • groupSum5(0,

  • groupSum5(0,{2,5,10,4},17)→true

  • groupSum5(0,{2,5,10,4},12)→false

  • {3,5,1},5)→true

{3,5,1},4) 假→

该函数是公共布尔groupSum5(int,int[] num,int目标)。

我已经编写了部分代码,但是也有失败的测试用例。

代码语言:javascript
运行
复制
     public boolean groupSum5(int start, int[] nums, int target) {     
           start = 0;     
           boolean flag = false;     
           for(int i=0;i<nums.length;i++){     
             if(nums[i]%5==0){     
                  start+=nums[i];                   
             }else if((start != target) && (start%5==0)){     
                  start+=nums[i];       
             }else if(start == target){      
                  flag = true;      
                  return flag;     
             }else if((nums[i]%5==0) && (nums[i+1]==1)){      
                  continue;                
             }    
           }
            return flag;      
     }     

即使在编写了这段代码之后,所有的测试用例都失败了。很长一段时间以来,我都在努力争取这个仪式。

编辑迪兰特:你能给我提供的代码修复,因为我已经尝试了这么多,我不知道如何继续

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-13 05:58:22

这里有一个解决方案,,但请参阅之后的讨论

代码语言:javascript
运行
复制
package so5987154;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

public class Summation {
    /**
     * Sum of start and every element of the collection.
     * 
     * @param start
     *            starting value for the sum
     * @param list
     *            Collection to sum.
     * @return the sum.
     */
    private int sum(final Integer start, final Collection<Integer> list) {
        int sum = start;

        for (final int i : list) {
            sum += i;
        }

        return sum;
    }

    /**
     * Given an array of ints, is it possible to choose a group of some of the ints, such that the group sums to the given target
     * with these additional constraints: all multiples of 5 in the array must be included in the group. If the value immediately
     * following a multiple of 5 is 1, it must not be chosen.
     * 
     * @param start
     *            not used
     * @param nums
     *            array of int (input)
     * @param target
     *            target value for the summation
     * @return true if we found a group that meet the criteria.
     */
    public boolean groupSum5(final int start, final int[] nums, final int target) {
        // list of values that need to be included (multiple of 5)
        final List<Integer> fixed = Lists.newArrayList();

        // list of value that can be included (anything but 1 preceded by a multiple of 5)
        final List<Integer> candidates = Lists.newArrayList();

        // fills candidates and fixed
        for (int i = 0; i < nums.length; i++) {
            final int cand = nums[i];

            if (cand == 1 && i > 0) {
                final int prev = nums[i - 1];
                if (prev % 5 != 0) {
                    candidates.add(cand);
                }
            } else if (cand % 5 == 0) {
                fixed.add(cand);
            } else if (cand <= target) {
                candidates.add(cand);
            }
        }

        // compute the sum of fixed
        final int sumFixed = sum(0, fixed);

        // if the sum of fixed is equals to target we don't need to do anything because
        // we already know we need to return true.
        if (sumFixed == target) {
            return true; // NOPMD
        }

        // if the sum of fixed is greater than target we don't need to do anything because
        // we already know we need to return false (all multiple of 5 must be included)
        // If candidates is empty there's no way we can achieve the desired goal.
        if (sumFixed <= target && !candidates.isEmpty()) {
            // generates all subsets of candidates:
            // { 1, 2 } => {}, {1}, {2}, {1, 2}
            final Set<Set<Integer>> powerSet = Sets.powerSet(Sets.newHashSet(candidates));

            // for each found subset, computes the sum of the subset and add it to the sum of
            // multiples of 5 then compare it to target. If equals => return true.
            for (final Set<Integer> set : powerSet) {
                if (sumFixed + sum(0, set) == target) {
                    return true; // NOPMD
                }
            }
        }

        return false;
    }
}

相关测试:

代码语言:javascript
运行
复制
package so5987154.tests;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import so5987154.Summation;

@SuppressWarnings("PMD")
public class SummationTest {
    private final Summation s = new Summation();

    @Test
    public void testGroupSum5() {
        assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 19));
        assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 17));
        assertFalse(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 12));
        assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 19));
        assertTrue(s.groupSum5(0, new int[] { 3, 5, 1 }, 5));
        assertFalse(s.groupSum5(0, new int[] { 3, 5, 1 }, 4));
        assertTrue(s.groupSum5(0, new int[] { 3, 1 }, 4));
        assertFalse(s.groupSum5(0, new int[] { 3, 1 }, 2));
        assertTrue(s.groupSum5(0, new int[] { 1 }, 1));
    }
}

但是,您的签名参数start建议使用递归。在第一步中,您可以从ints数组中删除:

  • 所有倍数为5,并将其加为start
  • all 1,先于5

的倍数。

然后用start和新的int数组调用您的方法。

在该方法中,您需要:

  • 测试如果开始等于目标=>返回真
  • 测试如果开始超过目标=>返回假
  • 测试如果数组为空,返回假
  • 调用带有开始+x的方法,其中x是数组的一个元素,以及x删除的=>返回或所有结果的数组(

F 220)

示例:{ 2,5,10,4 },目标= 19

倍数之和5: 5+10 = 15,NO1前面有5 =>新数组{ 2,4}

第一个呼叫:method(15, {2, 4}, 19)

  • start == => NO
  • start > => NO
  • 数组空=> NO
  • r1 =方法(15+2,{4},19)和r2 = method(15+4,{2},19)

F 231

第二次调用(r1):method(15+2, {4}, 19)

  • start == == => NO
  • start > => NO
  • 数组空=> NO
  • r11 =方法(15+2+4,{},19)

F 242

第三呼叫(r11):method(15+2+4, {}, 19)

false

  • start == target => NO
  • start > target => YES => =>

第二次调用(r2):method(15+4, {2}, 19)

true

  • start == target => YES => =>

我们回到了r1 = r11 = falser2 = true => return false OR true = true的第一次通话结束。

您可以看到,Sets.powerSet等价于递归调用r(k)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5987154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档