Редактирование рекурсивного алгоритма: передача массива вместо строки в качестве аргумента для сохранения результатов вместо печати - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть этот код для поиска n комбинаций из массива с длиной k:

class Util
{
    // Function to print all distinct combinations of length k
    public static void recur(int[] A, String out, int n, int k)
    {
        // invalid input
        if (k > n) {
            return;
        }

        // base case: combination size is k
        if (k == 0) {
            System.out.println(out);
            return;
        }

        // start from next index till first index
        for (int i = n - 1; i >= 0; i--)
        {
            // add current element A[i] to output and recur for next index
            // (i-1) with one less element (k-1)
            recur(A, (A[i]) + " " + out, i, k - 1);
        }
    }

    public static void main(String[] args)
    {
        int[] A = {0, 1, 2, 3 };
        int k = 2;
        // process elements from right to left
        recur(A, "", A.length, k);
    }
}

, он работает нормально, и его основной метод печатает

2 3 
1 3 
0 3 
1 2 
0 2 
0 1 

Однако я хочу сохранить эти комбинации в списке: List<int[]> или List<List<Integer>>. Я попытался отредактировать алгоритм:

public static void recur(int[] A, List<Integer> out, int n, int k)
    {
        // invalid input
        if (k > n) {
            return;
        }

        // base case: combination size is k
        if (k == 0) {
            System.out.println(out);
            return;
        }

        // start from next index till first index
        for (int i = n - 1; i >= 0; i--)
        {
            out.add(A[i]);
            // add current element A[i] to output and recur for next index
            // (i-1) with one less element (k-1)
            recur(A, out, i, k - 1);
        }
    }

, но он не работает должным образом: он печатает

[3, 2]
[3, 2, 1]
[3, 2, 1, 0]
[3, 2, 1, 0, 2, 1]
[3, 2, 1, 0, 2, 1, 0]
[3, 2, 1, 0, 2, 1, 0, 1, 0]

для этого основного метода:

public static void main(String[] args)
        {
            int[] A = {0, 1, 2, 3 };
            int k = 2;
            recur(A, new ArrayList<>(), A.length, k);
        }

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вам не хватает Unchoose части Выберите - Исследуйте - Отмените подход в типичном возврате.

Ваш Выберите часть есть out.add(A[i])

Ваша Explore часть - recur(A, out, i, k - 1)

Ваша Unchoose часть должна быть для удаления элемента, который вы выбрали в последний раз, т.е. последний элемент списка: out.remove(out.size()-1)

1 голос
/ 21 февраля 2020

Первый случай с String ou t работает, потому что String является неизменяемым, так что вы можете передать его без ущерба для оригинала.

Второй случай с ArrayList выиграл не работает, потому что вы передаете ссылку , а при изменении содержимого "ссылки" вы изменяете оригинал.

...