Не могу понять, как эта рекурсивная функция оценивает

#recursion

Вопрос:

Пожалуйста, помогите мне понять, как следующий код всегда возвращает наименьшее значение в массиве. Я попытался переместить позицию 3, но ей всегда удается вернуть ее, независимо от ее положения в массиве.

 let myA = [12,3,8,5] let myN = 4  function F4(A,N) {  if(N==1){  return A[0]  }  if(F4(A,N-1) lt; A[N-1]){  return F4(A,N-1)  }  return A[N-1] }  console.log(F4(myA,myN))  

Ответ №1:

Это довольно сложно понять интуитивно. Также очень важно, чтобы вы изучили процесс решения такого рода проблем, а не просто получили ответ.

Если мы сначала рассмотрим код с несколькими комментариями и именованными переменными, он выглядит так:

 let myA = [12,3,8,5]; let myN = myA.length;  function F4(A, N) {  // if (once) there is only one element in the array "A", then it must be the minimum, do not recurse  if (N === 1){  return A[0]  }   const valueFromArrayLessLastEl = F4(A,N-1); // Goes 'into' array  const valueOfLastElement = A[N-1];   console.log(valueFromArrayLessLastEl, valueOfLastElement);    // note that the recursion happens before min(a, b) is evaluated so array is evaluated from the start  if (valueFromArrayLessLastEl lt; valueOfLastElement) {  return valueFromArrayLessLastEl;  }   return valueOfLastElement; }  console.log(F4(myA, myN))  

и производит

 12 3 // recursed all the way down 3 8 // stepping back up with result from most inner/lowest recursion 3 5 3  

но для того, чтобы получить представление, жизненно важно, чтобы вы подошли к проблеме, рассмотрев простейшие случаи, и расширили оттуда. Что произойдет, если мы напишем код для случаев N = 1 и N = 2 :

 // trivially take N=1 function F1(A) {  return A[0]; }  // take N=2 function F2(A) {  const f1Val = F1(A); // N-1 = 1  const lastVal = A[1];   // return the minimum of the first element and the 2nd or last element  if (f1Val lt; lastVal) {  return f1Val;  }   return lastVal; }  

Пожалуйста, обратите внимание, что массив не изменяется, я говорю так, как будто это происходит потому, что значение N уменьшается при каждой рекурсии.

С myA = [12, 3, 8, 5] F1 всегда будет возвращать 12. F2 будет сравнивать это значение 12 с 3, значением n-го элемента-1, и возвращать минимальное значение.

Если вы сможете опираться на это, чтобы понять, что F3 будет делать, тогда вы сможете экстраполировать оттуда.

Поиграйте с этим, переупорядочивая значения myA , но главное, посмотрите на результат, когда вы увеличите N с 1 до 4.


В качестве примечания: переместив рекурсивный вызов F4(A,N-1) на локальную константу, я предотвратил его повторный вызов с одинаковыми значениями.

Комментарии:

1. Спасибо, Анди2К11. Это потрясающее объяснение.