Один тест не пройден, как это исправить? - PullRequest
0 голосов
/ 17 октября 2019

Я много раз пытался исправить ошибку с помощью метода void sameNumbers(), но до сих пор не нашел решения.

Отказы Junit: выход junit

Проблема в том, что, когда первый массив равен [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 ]

2 голосов
/ 17 октября 2019

Эти циклы не могут поместить значимое значение в найденное.

        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 является подмножествомзначений 2..

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 голосов
/ 17 октября 2019

В вашем цикле for он проверяет [0] и приравнивает его к ложному, но вы не прерываете цикл for после того, как он установлен в false, поэтому он проверяет [1] и заканчивается с found = true

1 голос
/ 17 октября 2019
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 }));

            }
        }
    }
1 голос
/ 17 октября 2019

После того, как вы отсортировали массивы values1 и values2, вы можете использовать equals функцию Массивы (как вы уже сделали):

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

Эта функцияуже проверяет, все ли записи и длины обоих массивов одинаковы. Таким образом, вы можете вернуть результат напрямую. Вам не нужно делать больше.

РЕДАКТИРОВАТЬ:

После вашего комментария: я пропустил ограничение. Сначала вы можете удалить дубликаты в массивах values1 и values2 с помощью набора:

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] и равны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...