Вот игра по пьесе исполнения:
Вы звоните findShortestString()
сами
Если Ло не равно, привет, дела продолжаются. В противном случае они останавливаются здесь, и функция возвращает.
Как только вы снова вызываете findShortestString()
, все в этом экземпляре функции полностью останавливается и не возобновит работу, пока у компьютера не будет значения, чтобы дать minindex
(иначе функция возвращается.) Мы начнем все заново в новом экземпляре функция наверху. Единственный код, выполняемый до тех пор, пока одна из функций не вернется, это код ДО вызова метода. Это можно сравнить с циклом while.
Мы выходим за эту строку только после того, как один из экземпляров функции имеет lo==hi
и возвращает.
Управление переключается на экземпляр функции до этого, который присваивает возвращаемое значение lo
minindex
.
Если (safeStringLength(paths[lo])<safeStringLength(paths[minindex]))
, то мы return lo
. Остальное у нас return minindex
. В любом случае, этот экземпляр функции завершен, и управление возвращается к предыдущему.
Каждая вызываемая функция теперь только выполняет код ПОСЛЕ вызова метода, поскольку метод не будет вызываться снова. Мы раскручиваем стек вызовов. Все возвраты теперь будут из последних 2 операторов, так как код сверху не будет выполнен снова. Обратите внимание, как только один экземпляр функции возвращается с верхней частью кода, завершая цикл while. Все остальные завершаются операторами возврата в части функции после рекурсивного вызова.
В конце концов последняя функция возвращается, и вы возвращаетесь к коду, из которого вызывали функцию изначально.
Вот более читаемая версия того, что на самом деле делает код:
В коде перед рекурсивным вызовом все, что происходит, - это создание цепочки вызовов до lo==hi
. Каждый раз, когда функция вызывается, когда lo больше 1. Вот пример стека вызовов:
findShortestString(2,5);
findShortestString(3,5);
findShortestString(4,5);
findShortestString(5,5);
Когда они раскручиваются, каждый экземпляр функции сравнивает длину строк в индексах lo и индекс предыдущего индекса с самой короткой строкой.
compare strings at indexes 2 and 5
if the string at 2 is smaller, compare the strings at indexes 2 and 4.
Otherwise, compare the strings with indexes at 3 and 5.
Если lo>hi
в начале, код будет продолжать выполняться до тех пор, пока lo не переполнит целое число и не станет отрицательным, затем до тех пор, пока lo наконец не доберется до hi, или 4,94,967,296 - (original lo - original hi) , Другими словами, это займет долгое время . Чтобы это исправить, добавьте проверку в начале метода, который выдает исключение, если lo>hi
.
Код может быть лучше переписан так:
static int findShortestString(String[] paths, int lo, int hi) {
int indexWithShortestString=lo;
for( int i=lo; i<=hi-1; i++) {
//assumption: lo and hi are both valid indexes of paths
if (paths[i+1].length < paths[i].length)
indexWithShortestString=i+1;
}
}