Сохранение данных в рекурсивной функции в список - PullRequest
1 голос
/ 07 марта 2019

Я работаю над функцией, которая разбивает данный ввод на деноминации с помощью рекурсивного вызова.

На каждом шаге он повторяется в двух вариантах:

  1. Продолжить с текущей монетой: добавить ее в список и повторить.
  2. Переключиться на следующую монету: увеличить позицию монеты и рекурсировать.

В дополнение к распечатке комбинации деноминаций, захваченных в списке при оставлении == 0, я намерен захватить значение этого списка и вернуть его из функции.

Вот код:

    static final int[] DENOMINATIONS = {9,5,3};

    private static void change(int remaining, List<Integer> coins, int pos)

        if (remaining == 0) {

       // This correctly prints the desired output. 
       // I want to return that exact value from the function.
            System.out.println(coins); 

        } else {
            if (remaining >= DENOMINATIONS[pos]) {
                coins.add(DENOMINATIONS[pos]);
                another.addAll(coins);
                change(remaining - DENOMINATIONS[pos], coins, pos);
                coins.remove(coins.size() - 1);
            }
            if (pos + 1 < DENOMINATIONS.length) {
                change(remaining, coins, pos + 1);
            }
        }
    }


    public static List<Integer> denominations(int amount) {
        List<Integer> result = new ArrayList<Integer>();
        List<Integer> another = new ArrayList<Integer>();
        change(amount, result, another ,0);
        System.out.println(another.size());
        return another;
    }

    public static void main(String[] args) {
        List<Integer> list = denominations(13);
        System.out.println(list);
    }

Выход: [5, 5, 3]

Ответы [ 3 ]

1 голос
/ 07 марта 2019

Вы, кажется, предполагаете, что Java передается по ссылке, что не соответствует действительности.Методы Java передаются по значению.

Я обновил ваш код:

метод изменения:

private static List<Integer> change(int remaining, List<Integer> coins, int pos) { // Updated method return type;

    if (pos < 0 || pos >= DENOMINATIONS.length) { // check if position is invalid
        return new ArrayList<>(); // return an empty list
    }

    if (remaining == DENOMINATIONS[pos]) { // check if remaining is equal to denominations[pos]
        coins.add(DENOMINATIONS[pos]); // add the denominations to the coins result
        return coins; // return the result
    } else if (remaining > DENOMINATIONS[pos]) { // check if remaining is greater than denominations[pos]
        coins.add(DENOMINATIONS[pos]);// add the possible denominations to the coins result
        remaining = remaining - DENOMINATIONS[pos]; // calculate the new remaining
        if (remaining >= DENOMINATIONS[pos]) { // check if remaining is greater than or equal to denominations[pos]
            return change(remaining, coins, pos); // stick to this position
        } else {
            return change(remaining, coins, pos + 1); // increment pos to go to the lower denominations
        }
    } else if (remaining < DENOMINATIONS[pos]) { // check if remaining is lesser than denominations[pos]
        if (coins.isEmpty()) { // if coins is empty then go to the next denomination
            return change(remaining, coins, pos + 1);
        } else {
            coins.remove(coins.size() - 1); // remove the previous denomination
            return change(remaining + DENOMINATIONS[pos - 1], coins, pos); // go back to the previous remaining and // try this DENOMINATIONS[pos]
        }
    }
    return coins;
}

метод номиналов:

public static List<Integer> denominations(int amount) {
    return change(amount, new ArrayList<Integer>(), 0);
}

ВХОД : 13
ВЫХОД : [5, 5, 3]

1 голос
/ 07 марта 2019

Вы должны добавить return coins; в методе и из change, но вы можете оставить его как есть.Возврат и изменение массива - это запах кода, поскольку метод работает с объектом (изменяет его) и возвращает результат.

Чтобы заставить его работать, вы можете определить свой метод denomination следующим образом:

public static List<Integer> denominations(int amount) {
   List<Integer> result = new ArrayList<Integer>();
   change(amount, result, 0);
   return result;
}

Редактировать:

Список пуст, поскольку единственное место, где он был изменен, это:

coins.add(DENOMINATIONS[pos]);
change(remaining - DENOMINATIONS[pos], coins, pos);
coins.remove(coins.size() - 1);

Где элемент добавляется и удаляется.То, что вы написали, делает его пустым:)

Edit2:

Я бы предложил обойти вокруг второго объекта, который будет копией списка, который вы хотели бы вернуть, и немодифицировано.

0 голосов
/ 07 марта 2019

change должен возвращать логическое значение, означающее, был ли найден ответ.

Итак change тело выглядит так:

if (remaining == 0) {
  return true;
}
...
if (change(...)) return true;
...
return false;  // It's last line of body
...