Меньше чем 100% тестирование юнитов филиала.Как это исправить? - PullRequest
0 голосов
/ 26 октября 2018

У меня есть запомненная рекурсивная функция для вычисления чисел Фибоначчи.У меня есть контрольные примеры для этой функции.По сути, он отправляет позицию, и если в этой позиции уже есть число, просто верните его, а если его нет, рассчитайте его.Я прогнал свой код через отладчик и понял, что:

if (dictionary[position] != null){
    result = dictionary[position];
  }

никогда не срабатывает.Полный код ниже.Например, если у вас есть Calculate Fib (4), который будет запрашивать fib(3), который будет запрашивать fib(2), который будет запрашивать fib(1), который будет запрашивать fib(0), и когда стек начинает закрываться, значенияникогда не сохраняютсятак, например, fib(2) или, скорее, dictionary(2) всегда равен нулю.Его запутанная причина в отладчике, который показывает, что значения вычисляются, но когда стек начинает закрываться, они снова становятся нулевыми.Как мне сделать рефакторинг кода, чтобы строки всегда были хитами?

public BigInteger calculateFib(int position) {

final BigInteger[] dictionary = new BigInteger[100000];

BigInteger result = BigInteger.ONE;

if (position < 2) {
  return result;
}
else {
  if (dictionary[position] != null){
    result = dictionary[position];
  }
  else {
    result = calculateFib(position - 1).add(calculateFib(position - 2));
    dictionary[position] = result;
  }
  return result

Ответы [ 4 ]

0 голосов
/ 26 октября 2018

Ваш код показывает 100% охват , если вы переместите dictionary за пределы метода.

Вот изображение, чтобы доказать это:

enter image description here

Однако , если я создаю «отчет о покрытии», он показывает 75% -е покрытие методом:

enter image description here

Этот отчет, очевидно, неверен, так как он показывает каждый отдельный метод и строку, попавшую под удар, и показывает 100% охват метода в IDE, поэтому я бы сказал, инструмент покрытия здесь неисправен ,Вы можете сообщить об ошибке.

0 голосов
/ 26 октября 2018

Вы должны объявить хранилище заметок вне вашего метода, так как он должен запоминать вещи при вызовах методов.Прямо сейчас вы создаете новый словарь хранилища "memo" для каждого вызова метода, поэтому вы ничего не помните.

Отнесите это вне вашего метода к экземпляру класса:

final BigInteger[] dictionary = new BigInteger[100000];

Как

class MyClass {
    final BigInteger[] dictionary = new BigInteger[100000];

    public BigInteger calculateFib(int position) {      
        BigInteger result = BigInteger.ONE;

        if (position < 2) {
          return result;
        }
        else {
          if (dictionary[position] != null){
            result = dictionary[position];
          }
          else {
            result = calculateFib(position - 1).add(calculateFib(position - 2));
            dictionary[position] = result;
          }
          return result
        }
    }
}
0 голосов
/ 26 октября 2018

Результат не будет memoize, как вы ожидаете.Каждый раз, когда вызывается метод, вы инициализируете новый словарь, который умирает, когда метод завершается.

Вам нужно извлечь переменную словаря и инициализировать ее вне метода.

final BigInteger[] dictionary = new BigInteger[100000];
0 голосов
/ 26 октября 2018

Каждый раз, когда вы звоните calculateFib() эта строка:

final BigInteger[] dictionary = new BigInteger[100000];

создает временный экземпляр массива dictionary[]Как только calculateFib() закончен, dictionary[] уничтожается.Если вы хотите сохранить значения и использовать их повторно, вы должны объявить их на уровне класса за пределами calculateFib(). Редактировать , это мой подход к вашей логике:

final BigInteger[] dictionary = new BigInteger[100000];

public BigInteger calculateFib(int position) {
    if (position < 0)
        return BigInteger.ZERO;

    BigInteger result = BigInteger.ONE;


    if (dictionary[position] != null) {
        result = dictionary[position];
    } else if (position < 2) {
        dictionary[position] = result;
    } else {
        result = calculateFib(position - 1).add(calculateFib(position - 2));
        dictionary[position] = result;
    }

    return result;
}
...