Как найти ката с выбросом четности

#java #junit

#java #junit

Вопрос:

Я выполняю ката с поиском четности в Java. Я не уверен, почему, но мой тест junit завершается неудачей, поскольку он возвращает -10 вместо 3 для части первого теста. Если кто-нибудь может, пожалуйста, дайте мне знать, почему это так? Тест завершается неудачей в примере test1, поскольку он возвращает -10 вместо 3.

Обновление Я внес изменения в свой код (пожалуйста, смотрите Ниже), чтобы сделать следующее. Итак, теперь он проходит все тесты в eclipse, но по какой-то причине все еще терпит неудачу на веб-сайте code wars. Сообщение об ошибке expected:amp;<2amp;> but was:amp;<7amp;>

 import java.util.ArrayList;

public class FindOutlier {

    private ArrayList<Integer> odds = new ArrayList<Integer>();
    private ArrayList<Integer> evens = new ArrayList<Integer>();

    public static void main(String[] args) {

    }

    public int find(int[] integers) {
        int finalResult = 0;

        for (int i = 0; i < integers.length; i  ) {
            if (integers[i] % 2 != 0) {
                odds.add(integers[i]);
            } else {
                evens.add(integers[i]);
            }
        }

        if (evens.size() > odds.size()) {
            finalResult  = odds.get(odds.size()-1);

        } else {

            finalResult  = evens.get(evens.size()-1);

        }

        return finalResu<

    }
}
  

и вот тест jnuit

 package Tests;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import Supermarket_Pricing.FindOutlier;

public class OutlierTest{
    private FindOutlier foo;

@Before
public void setup(){
    foo = new FindOutlier();

}

 @Test
 public void testExample() {
     int[] exampleTest1 = {2,6,8,-10,3}; 
     int[] exampleTest2 = {206847684,1056521,7,17,1901,21104421,7,1,35521,1,7781}; 
     int[] exampleTest3 = {Integer.MAX_VALUE, 0, 1};
     assertEquals(3, foo.find(exampleTest1));
     assertEquals(206847684, foo.find(exampleTest2));
     assertEquals(0, foo.find(exampleTest3));
 }}
  

Комментарии:

1. делая это: odds = new ArrayList<Integer>(Arrays.asList(integers[i])); для коэффициентов и четности вы не перезаписываете или не создаете новые объекты каждый раз

2. Я думаю, что вы делаете ката неправильно: удалите то, что у вас есть до сих пор. Начните с проверки простого возможного поведения . (например, список с одним элементом в качестве входных данных). Затем реализуйте это поведение, но не более того. Затем напишите другой тест , который запрашивает что-то более сложное. Реализуйте это и продолжайте таким образом.

3. Кстати: в эти выходные globalday.coderetreat.org найдите ближайшее к вам событие, к которому вы можете присоединиться!

4. @TimothyTruckle тест был доступен в code wars, он уже был написан

5. на самом деле ката кодирования собирается написать свой собственный код. Я почти уверен, что вам не нужна практика в копировании / вставке … ; о)

Ответ №1:

Ваш алгоритм неверен: odds и evens не представляют списки нечетных и четных чисел; вместо этого они представляют одноэлементный список, содержащий последнее найденное нечетное или четное значение.

Когда вы запускаете свою программу в первом примере, odds является [3] и evens является [-10] (последнее нечетное и последнее четное число соответственно). Ваше if условие структурировано таким образом, чтобы предпочесть четность коэффициентам, объясняя возврат.

Поскольку проблема задана таким образом, что всегда есть только один выброс, вам вообще не нужны дополнительные коллекции. Вы можете структурировать свой алгоритм таким образом:

  • Возьмите первые три числа (проблема гарантирует, что их будет как минимум три)
  • Подсчитайте количество шансов среди первых трех чисел
  • Подсчитайте количество четных чисел среди первых трех чисел
  • Если у вас больше шансов, чем четных, найдите и верните первое четное число
  • Если у вас больше четных, чем шансов, найдите и верните первое нечетное число

Вот простая реализация:

 int firstThreeParity = integers[0]%2   integers[1]%2   integers[2]%2;
int rem = firstThreeParity < 2 ? 1 : 0;
for (int i = 0; i < integers.length; i  ) {
    if (integers[i] % 2 == rem) {
        return integers[i];
    }
}
return -1; // If the input is correct, we'll never reach this line
  

Комментарии:

1. когда вы говорите взять первые три числа, вы имеете в виду цикл for?

2. @user6248190 Нет, первого или второго цикла не будет — вам понадобится только один цикл во всей программе. Вычислить integers[0]%2 integers[1]%2 integers[2]%2 . Если оно равно нулю или единице, найдите первое нечетное число; в противном случае найдите первое четное число.

3. не могли бы вы объяснить, что делает переменная rem. что означает firstThreeParity < 2? 1: 0; означает?

4. @user6248190 Цикл ищет первое нечетное или первое четное число. Нечетное число имеет остаток от 1 , когда вы вызываете %2 его; четное число имеет остаток от 0 . Переменная rem устанавливается в «целевой» остаток — ноль, когда мы ищем четное число, или единицу, когда мы ищем нечетное.

5. извините, еще одна вещь, не могли бы вы объяснить синтаксис для rem? Я никогда не сталкивался с вопросительным знаком в Java. Я также думал, что двоеточие используется только для циклов

Ответ №2:

Вот самый простой метод, который я видел онлайн:

 int sum = Arrays.stream(integers).limit(3).map(i -> Math.abs(i) % 2).sum();
int mod = (sum == 0 || sum == 1) ? 1 : 0;

    
return Arrays.stream(integers).parallel().filter(n -> Math.abs(n) % 2 == mod).findFirst().getAsInt();
  
  1. Поскольку мы предупреждены, что массив может быть очень большим, нам следует избегать подсчета значений больше, чем это необходимо. Нам нужны только первые 3 целых числа, чтобы определить, преследуем ли мы шансы или четы.

  2. Итак, возьмите первые 3 целых числа и вычислите значение Math.abs(i) % 2 для каждого из них.Это будет 0 для четных чисел и 1 для нечетных чисел.

  3. Теперь добавьте их. Если сумма равна 0 или 1, то мы ищем шансы. Если сумма равна 2 или 3, то мы ищем четности.

Ответ №3:

Попробуйте это в своем цикле for, и это должно сработать:

 for (int i = 0; i < integers.length; i  ) {
            if (integers[i] % 2 != 0) {
                odds.add(integers[i]);
            } else {
                evens.add(integers[i]);
            }
 }
  

Проблема в вашем коде заключалась в том, что каждый раз, когда вы создавали новый экземпляр нечетного и четного, только последний элемент сохранялся в odds и evens…