Рекурсия с '|' или '||' оператор не возвращает false в базовом случае - PullRequest
0 голосов
/ 17 февраля 2020

Итак, я смотрю на метод рекурсии, который использую для решения задачи кода. Я считаю, что это может быть просто недоразумением с моей стороны. Вот рекурсивная функция.

    public static boolean canSum(int[] arr, int max)
    {
        System.out.println(Arrays.toString(arr));
        if(max == 0) return true;
        if(arr.length == 0) return false;
        else return canSum(Arrays.copyOfRange(arr, 1, arr.length), max) | canSum(Arrays.copyOfRange(arr, 1, arr.length), max-arr[0]);
    }

Теперь она работает так, что в конечном итоге она выдаст мне true или false, если целые числа в моем массиве в любой комбинации дадут мне максимальное значение, которое я ищу, или он вернет ложь. Чего я не понимаю, так это того, что если я System.out.println(Arrays.toString(arr) вижу, что мой массив уменьшается до 0, то, если я отлаживаю, он попадает в строку if(arr.length == 0) return false;. Так почему же функция не прерывается и возвращает false. Эта рекурсивная функция продолжает работать по существу. Вот консольные массивы, которые я вижу для этого варианта использования Я не понимаю оператора | (Я думаю, что || работает также) и почему мне нужно max=arr[0]. Основываясь на отладке, похоже, что canSum(Arrays.copyOfRange(arr, 1, arr.length), max-arr[0]) запускается, когда моя arr.length = 0. Так действительно ли OR здесь как троичное здесь для рекурсивного вызова функции? Я не уверен, как 'вернуть recurseFunct (n-1, m) | recurseFunct (n-1, mn [0]) 'точно работает в этом сценарии. Это кажется очень удобным, и я хотел бы понять это лучше.

****** Добавление этого видео, поскольку оно поддерживает принятый ответ *******

Вы можете визуально увидеть стек, который используется в этом рекурсе, слева сторона отладчика. Размер стека немного меняется, пока он окончательно не опустошится полностью. После опустошения я верну true или false в рекурсивной функции в этой точке. Это был хороший опыт для меня. Спасибо!

enter image description here

1 Ответ

2 голосов
/ 17 февраля 2020

Если я отлаживаю, он появляется в строке, если (arr.length == 0) возвращает false ;. Так почему же функция не прерывается и возвращает false. Эта рекурсивная функция продолжает работать по существу.

Последовательность вызова функции подобна приведенной ниже. (индекс в скобках).

                 call(0)
                /       \
        call(1)     ||     call(4)
        /     \             /    \
    call(2) || call(3)  call(5) || call(6)  
    /\          /\      /\          /\
   /  \        /  \    /  \        /  \

Вызов функций будет сохранен в стеке, как показано ниже

call(2)
call(1)
call(0)

, если call (2) вернет false, он вызовет pop (2) ) из стека и возвращайтесь к call (1) и pu sh call (3) в стек.

call(3)
call(1)
call(0)

, если call (3) возвращает false, он вызовет call (3) из стека , вернитесь к вызову (1), вызов (1) вернется (вызов (2) || вызов (3)), вызов вызова (1) из стека, возврат к вызову (0) и вызов pu sh ( 4).

, поэтому, даже если какой-либо вызов функции вернет false, оставшаяся группа вызовов будет выполнена, и поэтому

рекурсивная функция продолжает работать по существу

...