检查列表中的元素是否为12的倍数

时间:2018-03-20 23:37:04

标签: java recursion arraylist

我给了一个列表,我试图递归检查列表中的相邻元素是否是12的倍数,如果是,那么我需要检查列表中剩余的数字是否为奇数。例如,[6,6,5]返回true,[6,5,6,1]返回false。我遇到了[10,7,5,5]返回true的情况,因为(7 + 5)= 12(12的倍数)和(10 + 5)= 15(奇数)。这是我的代码。它在元素为0和1索引时起作用,但在倍数在中间时不起作用。

public static boolean twoGroups(List<Integer> t) {
    if(t.size()  < 2 ) {
        return false;
    }

    if((t.get(0) * t.get(1)) % 12 == 0){
        List<Integer> i = new ArrayList<>(t);
        i.remove(0);
        i.remove(1);
        int works = checkSum(i, 0);
        if(works % 2 == 0) {
            return true;
        }else {
            return false;
        }

    }else { // I think this is where I am going wrong
        List<Integer> i = new ArrayList<>(t);
        List<Integer> newList = new ArrayList<>();
        newList.add(i.get(0));
        i.remove(0);
        return twoGroups(i);
    }

}


/*
 * returns true if the sum of the elements of the list is odd
 *Helper method
 */
public static int checkSum(List<Integer> t, int index) {
    if(t.size() == index) {
        return 0;
    }

    return t.get(index) + checkSum(t, index + 1);
}

我在我认为我出错的部分评论过。 Plz帮助

4 个答案:

答案 0 :(得分:4)

我相信你有一些问题。

  1. 在第6行乘以 t.get(0) * t.get(1) % 12 == 0。根据您提供的说明,您应该添加。 [10,7,5,5]乘以10 * 7,等于70(12的倍数)。
  2. 第8行&amp; 9 i.remove(0); i.remove(1);不会按您的意愿删除变量。首先,从[10,7,5,5] - &gt; [7,5,5]中删除10(索引0)。然后,删除5(新索引1)[7,5]
  3. 您将遍历的变量添加到List<Integer> newList = new ArrayList<>();,但该变量从未使用过。您应该使用该列表以及List t中的其余变量来查找总和。

答案 1 :(得分:0)

这应该有效:

public class Divisible {

    public boolean divisibleBy12(List<Integer> numbers) {
        return divisibleHelper(numbers, 0);
    }

    private boolean divisibleHelper(List<Integer> numbers, int currentIndex) {
        if(numbers.size() <= currentIndex -1) {
            return false;
        } else if(currentIndex + 1 < numbers.size() 
                && isDivisible(numbers.get(currentIndex), numbers.get(currentIndex + 1))) {
            return getSum(numbers, numbers.get(currentIndex), numbers.get(currentIndex + 1));
        } else {
            return divisibleHelper(numbers, currentIndex + 1);
        }
    }

    private boolean getSum(List<Integer> numbers, Integer num1, Integer num2) {
        int sum = numbers.stream().mapToInt(Integer::intValue).sum() - num1 - num2;
        return (sum & 1) == 1;
    }

    private boolean isDivisible(Integer num1, Integer num2) {
        return (num1 + num2) % 2 == 0;
    }
}

您的问题是从列表中删除元素,因此您无法计算总和中的元素。代码有点乱,所以我会留给你整理它。

答案 2 :(得分:0)

我在Scala中只有一个解决方案,它在Java中易于翻译,但部分不是这样 - 至少我不习惯新引入的Java功能部分,我不断在不同的集合之间丢失具有不同的能力。

如果我们转动List,我们可以先检查子列表是否为奇数。只有这样,我们才会逐步测试列表的其余部分,以便加起来为12的倍数:

// easy: sum of list is odd/multiple of 12
def isOdd (l: List[Int]): Boolean = { (l.sum % 2 == 1) }
def dozenix (l: List[Int]): Boolean = { (l.sum % 12 == 0) }
// For (1,8,7,6) test 1 => 1, 8 => 1, 8, 7 => 1, 8, 7, 6
def findDozenic (fromFront: List[Int]): Boolean = {
    (1 to fromFront.size - 1).exists (i => dozenix (fromFront.take (i)))
}
// for (a,b,c,d) test (a)(bcd), (ab)(cd), (abc)(d)
def dozenAfterOddRest (rest: List[Int]): Boolean = {
    for (i <- (1 to rest.length - 1);
    if isOdd (rest.take (i));
    if findDozenic (rest.drop (i))) return true
    return false
}
// initial method to call, turning the list around
def restAfterDozen (rest: List[Int]): Boolean = {
    dozenAfterOddRest (rest.reverse)
}

测试:

scala> val samples = (1 to 10).map (dummy => (1 to 5).map (foo => {rnd.nextInt (15)+1;}).toList)
samples: scala.collection.immutable.IndexedSeq[List[Int]] = Vector(List(13, 3, 14, 8, 2), List(8, 13, 5, 4, 6), List(5, 1, 5, 12, 1), List(5, 14, 15, 8, 2), List(1, 6, 15, 2, 12), List(1, 1, 13, 15, 8), List(4, 15, 2, 10, 8), List(2, 12, 1, 7, 2), List(7, 9, 4, 9, 8), List(6, 8, 7, 15, 8))

scala> samples.map (restAfterDozen)
res107: scala.collection.immutable.IndexedSeq[Boolean] = Vector(false, false, true, false, false, false, false, false, false, false)

作为一个真实的结果,List(5,1,5,12,1)显然是正确的。最后一个元素1是奇数,在它前面是12,它是12的div。我没有检查其他列表,但更改了代码,使示例更易读:

def dozenAfterOddRest (rest: List[Int]): Boolean = {
    for (i <- (1 to rest.length - 1);
    if isOdd (rest.take (i));
    if findDozenic (rest.drop (i))) {
        println (rest.drop (i).reverse.mkString ("+") + "> -- <" + rest.take(i).mkString ("+"));
        return true
    }
    return false
}

所以

Vector(List(1, 3, 3, 8, 2, 7, 3, 7, 5), List(2, 2, 8, 11, 9, 4, 5, 5, 9), List(10, 10, 8, 9, 1, 4, 8, 5, 6), List(3, 10, 2, 6, 3, 2, 10, 4, 2), List(7, 5, 6, 5, 11, 6, 8, 1, 2), List(11, 4, 1, 1, 4, 1, 4, 4, 6), List(3, 10, 1, 11, 8, 2, 8, 3, 11), List(10, 1, 10, 7, 6, 2, 6, 2, 11), List(10, 9, 10, 9, 3, 8, 9, 5, 4), List(2, 8, 5, 2, 9, 7, 4, 3, 1))

打印(仅匹配):

scala> samples.map (restAfterDozen)
2+2+8+11+9+4> -- <9+5+5   // 9+5+5 is Odd, 4+9=13, +11=24 
10+10+8+9+1+4+8> -- <6+5  // 6+5 odd, 8+4=12
3+10+2> -- <2+4+10+2+3+6  // and so on.
7+5+6+5+11+6+8> -- <2+1
10+1+10+7+6> -- <11+2+6+2
10+9+10+9+3+8+9> -- <4+5
2+8+5+2+9> -- <1+3+4+7
res115: scala.collection.immutable.IndexedSeq[Boolean] = Vector(false, true, true, true, true, false, false, true, true, true)

答案 3 :(得分:0)

这是我在Java中的解决方案;它可以作为上面的scala解决方案,而不仅仅是4个元素的列表。代码以方便方法开头,你必须从底部读取它,方法在哪里,称为:

int sum (List<Integer> l) {
    return (l.stream().reduce(0, (x,y) -> x+y));
}

boolean isOdd (List<Integer> l) { 
     return (sum(l) % 2 == 1); 
}

boolean dozenix (List<Integer> l) { 
    return (sum(l) % 12 == 0); 
}

// For (1,8,7,6) test 1 => 1, 8 => 1, 8, 7 => 1, 8, 7, 6
boolean findDozenic (List<Integer> fromFront) {
    for (int i = 1; i < fromFront.size() - 1; ++i)
        if (dozenix (fromFront.subList (0, i)))
            return true;
    return false;
}

// for (a,b,c,d) test (a)(bcd), (ab)(cd), (abc)(d)
boolean dozenAfterOddRest (List<Integer> rest) {
    for (int i = 1; i < rest.size () - 1; ++i)
        if (isOdd (rest.subList (0, i)))
            if (findDozenic (rest.subList (i, rest.size () - 1))) 
                return true;
    return false;
}

// initial method to call, turning the list around
boolean restAfterDozen (List<Integer> input) {
    Collections.reverse (input);
    return dozenAfterOddRest (input);
}

由于其余几十之后的其余部分必须是奇数,我从头开始,寻找一个奇数的总和,因为我们必然会结束列表,而对于部分,总和达到的倍数12,它们可以长到最终,收缩到最后或收缩在头部。容易丢失概述。

从最后很容易。最后数字奇数?然后尝试从它前面的数字构建divBy12 - 只是一个顺序任务。如果总和不是奇数,则取一个下一个数字再试一次,直到(前)列表头(现在列表末尾)。