一项测试失败,该如何解决?

时间:2019-10-17 10:08:04

标签: java arrays junit

我已经尝试过很多次来修复方法void sameNumbers()中的失败,但仍然没有找到解决方案。

Junit失败: junit output

问题是,当第一个数组为[1]而第二个数组为[0, 1]时,它将返回true,而不是false

有人可以解释并帮助我解决此问题吗?

谢谢。

public class SameNumbers {

    public static boolean sameNumbers(int[] values1, int[] values2) {

        Arrays.sort(values1);
        Arrays.sort(values2);
        boolean found = false;

        if (values1.length == 0 && values2.length == 0) {
            found = true;
        } else if (values1.length == 0 && values2.length > 0 || values1.length > 0 && values2.length == 0) {
            found = false;
        } else if (Arrays.equals(values1, values2)) {
            found = true;
        } else if (values1.length > 0 && values2.length > 1 || values1.length > 1 && values2.length > 0) {
            for (int i = 0; i < values1.length; i++) {
                for (int k = 0; k < values2.length; k++) {
                    if (values1[i] == values2[k]) {
                        found = true;
                    } else {
                        found = false;
                    }
                }
            }

        }

        return found;

    }
}
class SameNumbersTest {

    static final int nbrTests = 20;
    private Random random = new Random();

    @Test
    void sameNumbers1() {
        Assertions.assertEquals(true, SameNumbers.sameNumbers(new int[] {}, new int[] {}),
                "SameNumbers.sameNumbers(new int[]{}, new int[]{})");
    }

    @Test
    void sameNumbers2() {
        for (int i = 0; i < nbrTests; i++) {
            int r = random.nextInt(20);
            Assertions.assertFalse(SameNumbers.sameNumbers(new int[] {}, new int[] { r }),
                    "SameNumbers.sameNumbers(new int[]{}, new int[]{r})");
            Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { r }, new int[] {}),
                    "SameNumbers.sameNumbers(new int[]{r}, new int[]{})");
            Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { r }, new int[] { r }),
                    "SameNumbers.sameNumbers(new int[]{r}, new int[]{r})");
        }
    }

    @Test
    void sameNumbers3() {
        for (int i = 0; i < nbrTests; i++) {
            int r = random.nextInt(20);
            if (r != 1) {
                Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }),
                        "SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})");
                Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }),
                        "SameNumbers.sameNumbers(new int[]{r, 1}, new " + "int[]{1})");
            } else {
                Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }),
                        "SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})");
                Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }),
                        "SameNumbers.sameNumbers(new int[]{r, 1}, new int[]{1})");
            }
        }
    }

    @Test
    void sameNumbers4() {
        Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 2, 1 }),
                "SameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 2, 1})");
        Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 3, 2, 1 }),
                "SameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 3, 2, 1})");
        Assertions.assertFalse(SameNumbers.sameNumbers(new int[] { 1, 2, 3 }, new int[] { 3, 4, 2, 1 }),
                "ameNumbers.sameNumbers(new int[]{1, 2, 3}, new int[]{3, 4, 2, 1})");
        Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2 }, new int[] { 2, 1, 1 }),
                "SameNumbers.sameNumbers(new int[]{1, 2}, new int[]{2, 1, 1})");
        Assertions.assertTrue(SameNumbers.sameNumbers(new int[] { 1, 2, 2 }, new int[] { 2, 1, 1 }),
                "SameNumbers.sameNumbers(new int[]{1, 2, 2}, new int[]{2, 1, 1})");
    }

}

4 个答案:

答案 0 :(得分:2)

在for循环中,它检查[0]并将其等于false,但是一旦将其设置为false,就不会中断for循环,因此它会检查[1]并以found = true结尾

答案 1 :(得分:2)

这些循环无法在found中添加有意义的值。

        for (int i = 0; i < values1.length; i++) {
            for (int k = 0; k < values2.length; k++) {
                if (values1[i] == values2[k]) {
                    found = true;
                } else {
                    found = false;
                }
            }
        }

可以写为

        found = values1[values1.length - 1] == values2[values2.length - 1];

您打算进行如下操作,以检查values1是values2的子集。

WRONG:
        found = true;
        for (int i = 0; i < values1.length; i++) {
            found = false;
            for (int k = 0; k < values2.length; k++) {
                if (values1[i] == values2[k]) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                break;
            }
        }

当您对一个更好的算法进行排序时,将是:

public static boolean sameNumbers(int[] values1, int[] values2) {
    values1 = IntStream.of(values1).sorted().distinct().toArray();
    values2 = IntStream.of(values2).sorted().distinct().toArray();
    if (values1.length != values2.length) {
        return false;
    }
    for (int i = 0; i < values1.length; ++i) {
        if (values1[i] != values2[i]) {
            return false;
        }
    }
    return true;
}

public static boolean sameNumbers(int[] values1, int[] values2) {
    Arrays.sort(values1);
    Arrays.sort(values2);
    int i1 = 0;
    int i2 = 0;
    while (i1 < values1.length && i2 < values2.length) {
        if (values1[i1++] != values2[i2++]) {
            return false;
        }
        while (values1[i1] == values1[i1 - 1] { // Repetitions in values1
            ++i1;
        }
        while (values1[i2] == values1[i2 - 1] { // Repetitions in values1
            ++i2;
        }
    }
    return i1 == values1.length && i2 == values2.length;
}

public static boolean sameNumbers(int[] values1, int[] values2) {
    values1 = IntStream.of(values1).sorted().distinct().toArray();
    values2 = IntStream.of(values2).sorted().distinct().toArray();
    return Arrays.equals(values1, values2);
}

测试失败时,测试可能是错误的。

答案 2 :(得分:1)

对数组values1values2进行排序后,可以使用Arraysequals函数(就像您已经做过的那样):

Arrays.sort(values1);
Arrays.sort(values2);
return Arrays.equals(values1, values2)

此函数已经检查所有条目和两个数组的长度是否相同。 这样您就可以直接返回结果。 您不需要做更多的事情。

编辑:

您发表评论后:我错过了限制。 您可以先用一组集合消除数组values1values2中的重复项:

LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>(Arrays.asList(values));

Integer[] valuesWithoutDuplicates = linkedHashSet.toArray(new Integer[] {});

在集合中,每个值都是唯一的。通过将数组[1,2,3,3,4,5,5]从数组转换为集合,可以将其简化为[1,2,3,4,5]。转换回数组,将使您可以处理具有唯一元素的数组。

例如,如果您有两个数组[1,2,2,3]和[1,2,3,3,3]都将简化为[1,2,3]并相等。

答案 3 :(得分:1)

If you pass the value between 0-20 it will return true as your fourth condition is getting satisfied. So, intead of changing your if conditions you can put an interger value which greater that 20. 

public void sameNumbers3() {
        for (int i = 0; i < nbrTests; i++) {
            int r = random.nextInt(20);
            if (r != 1) {
                Assert.assertFalse("SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})",
                        SameNumbers.sameNumbers(new int[] { 21 }, new int[] { r, 1 }));
                Assert.assertFalse("SameNumbers.sameNumbers(new int[]{r, 1}, new " + "int[]{1})"
                        ,SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 21 }));

            } else {
                Assert.assertTrue("SameNumbers.sameNumbers(new int[]{1}, new int[]{r, 1})",
                        SameNumbers.sameNumbers(new int[] { 1 }, new int[] { r, 1 }));

                Assert.assertTrue("SameNumbers.sameNumbers(new int[]{r, 1}, new int[]{1})",
                        SameNumbers.sameNumbers(new int[] { r, 1 }, new int[] { 1 }));

            }
        }
    }