#arrays #c #recursion
Вопрос:
У меня есть небольшой вопрос о рекурсии. Приведенный ниже код на самом деле является ответом на вопрос Минимальное количество прыжков для достижения конца
// C program to find Minimum
// number of jumps to reach end
#include <limits.h>
#include <stdio.h>
// Returns minimum number of
// jumps to reach arr[h] from arr[l]
int minJumps(int arr[], int l, int h)
{
// Base case: when source and destination are same
if (h == l)
return 0;
// When nothing is reachable from the given source
if (arr[l] == 0)
return INT_MAX;
// Traverse through all the points
// reachable from arr[l]. Recursively
// get the minimum number of jumps
// needed to reach arr[h] from these
// reachable points.
int min = INT_MAX;
for (int i = l 1; i <= h amp;amp; i <= l arr[l]; i ) {
int jumps = minJumps(arr, i, h);
if (jumps != INT_MAX amp;amp; jumps 1 < min)
min = jumps 1;
}
return min;
}
// Driver program to test above function
int main()
{
int arr[] = { 1, 3, 6, 3, 2, 3, 6, 8, 9, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
printf(
"Minimum number of jumps to reach end is %d ",
minJumps(arr, 0, n - 1));
return 0;
}
Когда h==l и arr[l]==0, функция возвращает sth и функция заканчивается. В противном случае он обновляет переменную, называемую прыжками, но я не могу понять это утверждение. Например, какова величина скачков, когда i=1 или i=2 и так далее. Другими словами, я не могу понять смысл процесса обновления переменной прыжков.
Комментарии:
1. Мне непонятно, в чем заключается ваше сомнение. Я имею в виду… вы заметили, что
jumps
это присваиваетсяmin
, когда условие является правильным, а затемmin
возвращается.2. Рассматриваемая строка определяет вызываемую переменную
jumps
и присваивает ей значение, которое является значением, возвращаемым рекурсивным вызовом функцииminJumps()
. То есть выполняется один и тот же код, но передаются разные параметры. Компилятор реализует эти вызовы таким образом, что для каждого вызова функции точное состояние вызывающей функции запоминается и восстанавливается при возврате этой функции. Я надеюсь, что это немного поможет. (Я должен сказать, что этот пример-не лучший способ изучить рекурсию. дайте мне последовательность Фибоначчи в любой день.)3. Примечание: старайтесь не использовать строчные
l
буквы в качестве имени переменной. Это ужасно похоже на номер1
.
Ответ №1:
Возможно, ключ в том, чтобы внимательно прочитать и понять определение функции:
// Returns minimum number of
// jumps to reach arr[h] from arr[l]
int minJumps(int arr[], int l, int h)
Это довольно ясно.
Задача при реализации рекурсивной функции состоит в том, чтобы разбить проблему на базовый случай или случаи, а также рекурсивный шаг, который решает одну или несколько небольших проблем с рекурсивными вызовами, а затем использует результат для решения общей проблемы.
Базовый вариант здесь начинается и заканчивается в одном и том же месте. Никаких шагов не требуется. Верните 0.
(Автор также рассматривает нулевые элементы массива как особый случай. В этом не было необходимости. Программа работала бы так же, если бы эти строки были удалены.)
Рекурсивный шаг реализует эту идею:
Чтобы перейти от
l
доh
, сначала сделайте один шаг отl
доi
, а затем (рекурсивно) определите минимальное количество шагов S отi
доh
. Таким образом, общее количество шагов равно S 1.
Для чего выбирать i
? Единственный способ найти наименьшее количество шагов-это рассмотреть все возможности и выбрать минимальное. Эти возможности l 1
исчерпаны h
, т. е. начальный шаг длиной 1 вплоть до покрытия всего промежутка от l
до h
за один шаг (поэтому второй шаг имеет нулевую длину).