Во-первых, эта функция неверна. Я не могу сказать вам, что он пытается сделать, но он определенно не добавляет первые n элементов массива. Итак, как мы подходим к написанию одного? А что такое рекурсия?
Рекурсия не начиналась как идея программирования, она началась с математики, как и многие другие программные конструкции. Поэтому, прежде чем написать функцию суммирования, давайте определим ее математически:
f(arr, 0) = 0
f(arr, n) = f(n - 1) + arr[n - 1]
Я знаю, что массивы не используются как таковые в математике, но, черт возьми, это все еще полезно посмотреть. Первое, на что следует обратить внимание, это то, что существует два определения, а не одно. Первое определение говорит: сумма первых 0 элементов массива arr всегда равна 0. Независимо от того, что произошло до или после, она всегда будет равна 0.
Второе определение говорит, что для суммирования первых n элементы массива arr, мы должны найти сумму предыдущих элементов, а затем просто добавить arr[n - 1]
. Другой способ думать об этом, сумма первых n элементов, это просто сумма первых n - 1 элементов плюс n-й элемент . Это может вызвать головные боли, нет, это вызовет головные боли. Поэтому, чтобы уменьшить вашу боль, мы рассмотрим это шаг за шагом.
Скажем, я передаю функцию f([1, 2, 3, 4], 2)
, я должен получить 3. Вот как эта функция оценивается в 3:
f([1, 2, 3, 4], 2) = f([1, 2, 3, 4], 1) + [1, 2, 3, 4][1]
f([1, 2, 3, 4], 1) = f([1, 2, 3, 4], 0) + [1, 2, 3, 4][0]
f([1, 2, 3, 4], 0) = 0
И мы закончили. Какая? Были сделаны? Мы уверены, что есть. Обратите внимание, как мы определили каждый вызов функции, который мы сделали? Это означает, что мы можем работать в обратном направлении и заменять каждый вызов функции определением. Итак:
f([1, 2, 3, 4], 0) = 0
f([1, 2, 3, 4], 1) = 0 + 1 = 1
f([1, 2, 3, 4], 2) = 1 + 2 = 3
Просто выписав определения, мы можем оценить ответ. Это может быть сложно обдумать, но оценить его не легче, вот почему есть много похвал за рекурсивные функции. В любом случае, мы определили это математически, теперь мы можем действительно легко реализовать его на JavaScript или на любом языке по вашему выбору - при условии, что он поддерживает рекурсию.
function sum(arr, n)
{
if (n <= 0) return 0; // f(arr, 0) = 0
return sum(arr, n - 1) + arr[n - 1]; // f(arr, n) = f(arr, n - 1) + arr[n - 1]
}
Несколько вещей замечать. Вы не можете иметь рекурсию, если функция не возвращает что-то, так как при оценке функция полагается на подстановку. И каждая рекурсивная функция должна иметь как минимум два определения, чтобы l oop мог закончиться. Кроме того, вы видите, как код почти соответствует математическим определениям один к одному? Я знаю, это действительно круто.
Редактировать: if (n == 0)
нормально, но не работает, если n отрицательно. Итак, я заменил его на n <= 0
.