Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Recursion and stack#201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
tarasyyyk merged 17 commits intojavascript-tutorial:masterfromMykolaSopiha:recursion
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
17 commits
Select commitHold shift + click to select a range
7b6b656
recursion
MykolaSopihaSep 14, 2021
7b50e8f
recursion
MykolaSopihaSep 15, 2021
cf0d352
recursion
MykolaSopihaSep 17, 2021
4a314e0
recursion
MykolaSopihaSep 17, 2021
f238777
recursion
MykolaSopihaSep 19, 2021
6e39fea
recursion
MykolaSopihaSep 23, 2021
8674a1e
recursion
MykolaSopihaSep 24, 2021
a5e1aac
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
MykolaSopihaSep 24, 2021
5acec97
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
MykolaSopihaSep 24, 2021
590345a
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
MykolaSopihaSep 24, 2021
64e8cd1
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
MykolaSopihaSep 24, 2021
2edd88a
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
MykolaSopihaSep 24, 2021
d6f20ec
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
MykolaSopihaSep 24, 2021
1c20ecf
Update 1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
MykolaSopihaSep 24, 2021
dded194
Update 1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
MykolaSopihaSep 24, 2021
85814af
Update 1-js/06-advanced-functions/01-recursion/02-factorial/task.md
MykolaSopihaSep 24, 2021
380474e
Update 1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
MykolaSopihaSep 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
The solution using a loop:
Рішення з використанням циклу:

```js run
function sumTo(n) {
Expand All@@ -12,7 +12,7 @@ function sumTo(n) {
alert( sumTo(100) );
```

The solution using recursion:
Рішення з використанням рекурсії:

```js run
function sumTo(n) {
Expand All@@ -23,7 +23,7 @@ function sumTo(n) {
alert( sumTo(100) );
```

The solution using the formula: `sumTo(n) = n*(n+1)/2`:
Рішення з використанням формули: `sumTo(n) = n*(n+1)/2`:

```js run
function sumTo(n) {
Expand All@@ -33,8 +33,8 @@ function sumTo(n) {
alert( sumTo(100) );
```

P.S.Naturally, the formula is the fastest solution. It uses only 3operations for any number `n`.The math helps!
P.S.Звичайно, формула є найшвидшим рішенням. Вона використовує лише 3операції для будь-якого числа `n`.Математика допомагає!

The loop variant is the second in terms of speed. In both the recursive and the loop variant we sum the same numbers. But the recursion involves nested calls and execution stack management. That also takes resources, so it's slower.
Варіант з циклом є другим з точки зору швидкості. Як і у випадку рекурсії, в циклі ми сумуємо ті ж числа. Але рекурсія передбачає вкладені виклики та управління стеком. Це також займає ресурси, тому це повільніше.

P.P.S.Some engines support the "tail call" optimization: if a recursive call is the very last one in the function (like in`sumTo` above),then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory, so counting `sumTo(100000)`becomes possible. But if the JavaScriptengine does not support tail call optimization (most of them don't),there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
P.P.S.Деякі рушії підтримують оптимізацію "хвостового виклику" (tail call): якщо рекурсивний виклик є останнім в функції (як у випадку з`sumTo`),то зовнішня функція не повинна відновлювати виконання, отже рушію не потрібно запам’ятовувати контекст виконання. Це зменшує використання пам’яті, тому підрахунок `sumTo(100000)`стає можливим. Але якщо рушій JavaScriptне підтримує оптимізацію хвостового виклику (більшість з них не підтримує),то виникне помилка: максимальний розмір стека перевищиться, оскільки зазвичай є обмеження на загальний розмір стека.
22 changes: 11 additions & 11 deletions1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,11 +2,11 @@ importance: 5

---

#Sum all numbers till the given one
#Сума всіх чисел до даного

Write a function`sumTo(n)` that calculates the sum of numbers `1 + 2 + ... + n`.
Напишіть функцію`sumTo(n)`, що обчислює суму чисел `1 + 2 + ... + n`.

For instance:
Наприклад:

```js no-beautify
sumTo(1) = 1
Expand All@@ -17,20 +17,20 @@ sumTo(4) = 4 + 3 + 2 + 1 = 10
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050
```

Make 3solution variants:
Зробити 3варіанти рішення:

1.Using a for loop.
2.Using a recursion, cause`sumTo(n) = n + sumTo(n-1)`for `n > 1`.
3.Using the [arithmetic progression](https://en.wikipedia.org/wiki/Arithmetic_progression) formula.
1.Використання циклу.
2.Використання рекурсії, у випадку`sumTo(n) = n + sumTo(n-1)`для `n > 1`.
3.Використання формули [арифметичної прогресії](https://uk.wikipedia.org/wiki/Арифметична_прогресія).

An example of the result:
Приклад результату:

```js
function sumTo(n) { /*...your code ... */ }
function sumTo(n) { /*...ваш код ... */ }

alert( sumTo(100) ); // 5050
```

P.S.Which solution variant is the fastest? The slowest? Why?
P.S.Який варіант рішення є найшвидшим? Найповільнішим? Чому?

P.P.S.Can we use recursion to count`sumTo(100000)`?
P.P.S.Чи можемо ми використовувати рекурсію для підрахунку`sumTo(100000)`?
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
By definition, a factorial`n!`can be written as `n * (n-1)!`.
За визначенням, факторіал`n!`може бути записаний як `n * (n-1)!`.

In other words, the result of`factorial(n)`can be calculated as `n`multiplied by the result of`factorial(n-1)`.And the call for`n-1`can recursively descend lower, and lower, till `1`.
Інакше кажучи, результат`factorial(n)`може бути розрахований, як `n`помножений на результат`factorial(n-1)`.І виклик до`n-1`може рекурсивно спускатися нижче та нижче, аж до `1`.

```js run
function factorial(n) {
Expand All@@ -10,7 +10,7 @@ function factorial(n) {
alert( factorial(5) ); // 120
```

The basis of recursion is the value`1`.We can also make `0`the basis here, doesn't matter much, but gives one more recursive step:
Базисом рекурсії є значення`1`.Ми також можемо зробити `0`базисом, це не має великого значення, але дає ще один рекурсивний крок:

```js run
function factorial(n) {
Expand Down
12 changes: 6 additions & 6 deletions1-js/06-advanced-functions/01-recursion/02-factorial/task.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,17 +2,17 @@ importance: 4

---

#Calculate factorial
#Розрахувати факторіал

The [factorial](https://en.wikipedia.org/wiki/Factorial) of a natural number is a number multiplied by `"number minus one"`,then by `"number minus two"`, and so on till`1`.The factorial of`n`is denoted as `n!`
[Факторіал](https://uk.wikipedia.org/wiki/Факторіал) з натурального числа -- це число, помножене на `"число мінус один"`,потім на `"число мінус два"` і так до`1`.Факторіал`n`позначається як `n!`

We can write a definition of factorial like this:
Ми можемо написати визначення факторіалу наступним чином:

```js
n! = n * (n - 1) * (n - 2) * ...*1
```

Values of factorials for different `n`:
Значення факторіалів для різних `n`:

```js
1! = 1
Expand All@@ -22,10 +22,10 @@ Values of factorials for different `n`:
5! = 5 * 4 * 3 * 2 * 1 = 120
```

The task is to write a function `factorial(n)` that calculates `n!`using recursive calls.
Завдання полягає в тому, щоб написати функцію `factorial(n)`, яка обчислює `n!`за допомогою рекурсивних викликів.

```js
alert( factorial(5) ); // 120
```

P.S.Hint: `n!`can be written as `n * (n-1)!` For instance: `3! = 3*2! = 3*2*1! = 6`
P.S.Підказка: `n!`може бути записане як `n * (n-1)!`. Наприклад: `3! = 3*2! = 3*2*1! = 6`
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
#Loop-based solution
#Рішення на основі циклу

The loop-based variant of the solution:
Варіант рішення на основі циклу:

```js run
let list = {
Expand DownExpand Up@@ -30,7 +30,7 @@ function printList(list) {
printList(list);
```

Please note that we use a temporary variable`tmp` to walk over the list. Technically, we could use a function parameter`list` instead:
Зверніть увагу, що ми використовуємо тимчасову змінну`tmp`, щоб пройти по списку. Технічно ми могли б використовувати замість нього параметр функції`list`:

```js
function printList(list) {
Expand All@@ -43,15 +43,15 @@ function printList(list) {
}
```

...But that would be unwise. In the future we may need to extend a function, do something else with thelist. If we change `list`,then we lose such ability.
...Але це було б нерозумно. У майбутньому нам доведеться розширити функцію, зробити щось інше з `list`. Якщо ми змінюємо `list`,то ми втрачаємо таку здатність.

Talking about good variable names, `list`here is the list itself. The first element of it. And it should remain like that. That's clear and reliable.
Говорячи про хороші імена змінних, `list`тут -- це сам список. Його перший елемент. І це повинно залишитися так. Це ясно і надійний.

From the other side, the role of`tmp`is exclusively a list traversal, like `i`in the`for`loop.
З іншого боку,`tmp`використовується виключно проходу, як `i`у`for`циклі.

#Recursive solution
#Рішення через рекурсію

The recursive variant of `printList(list)`follows a simple logic: to output a list we should output the current element`list`,then do the same for `list.next`:
Рекурсивний варіант `printlist(list)`слідує простій логіці: вивести список, який ми повинні вивести поточний елемент`list`,а потім зробити те ж саме для`list.next`:

```js run
let list = {
Expand All@@ -70,19 +70,19 @@ let list = {

function printList(list) {

alert(list.value); //output the current item
alert(list.value); //виведіть поточний елемент

if (list.next) {
printList(list.next); //do the same for the rest of the list
printList(list.next); //зробіть те ж саме для решти списку
}

}

printList(list);
```

Now what's better?
Що ж тепер краще?

Technically, the loop is more effective. These two variants do the same, but the loop does not spend resources for nested function calls.
Технічно цикл є більш ефективним. Ці два варіанти роблять те ж саме, але цикл не витрачає ресурси для вкладених викликів.

From the other side, the recursive variant is shorter and sometimes easier to understand.
З іншого боку, рекурсивний варіант коротший, а іноді його легше зрозуміти.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,9 +2,9 @@ importance: 5

---

#Output a single-linked list
#Вивести одинозв’язаний список

Let's say we have a single-linked list (as described in the chapter <info:recursion>):
Скажімо, у нас є одинозв’язаний список (як описано в розділі <info:recursion>):

```js
let list = {
Expand All@@ -22,8 +22,8 @@ let list = {
};
```

Write a function`printList(list)` that outputs list items one-by-one.
Напишіть функцію`printList(list)`, що виводить список елементів один за одним.

Make two variants of the solution: using a loop and using recursion.
Зробіть два варіанти рішення: з використанням циклу та з використанням рекурсії.

What's better: with recursion or without it?
Що краще: з рекурсією чи без неї?
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
#Using a recursion
#Використання рекурсії

The recursive logic is a little bit tricky here.
Тут рекурсивна логіка трохи складна.

We need to first output the rest of the list and *then* output the current one:
Нам потрібно спочатку вивести останні елементи списку, а *потім* вивести поточний:

```js run
let list = {
Expand DownExpand Up@@ -31,13 +31,13 @@ function printReverseList(list) {
printReverseList(list);
```

#Using a loop
#За допомогою циклу

The loop variant is also a little bit more complicated then the direct output.
Варіант циклу також трохи складніше, ніж прямий вивід.

There is no way to get the last value in our`list`.We also can't "go back".
Немає можливості отримати останнє значення в нашому`list`.Ми також не можемо "повернутися назад".

So what we can do is to first go through the items in the direct order and remember them in an array, and then output what we remembered in the reverse order:
Отже, що ми можемо зробити, так це спочатку пройти елементи в прямому порядку і запам’ятати їх у масиві, а потім вивести те, що ми запам’ятали, в зворотному порядку:

```js run
let list = {
Expand DownExpand Up@@ -71,4 +71,4 @@ function printReverseList(list) {
printReverseList(list);
```

Please note that the recursive solution actually does exactly the same: it follows the list, remembers the items in the chain of nested calls (in the execution context stack),and then outputs them.
Зверніть увагу, що рекурсивне рішення фактично робить точно так само: проходиться списком, запам’ятовує елементи в ланцюжку вкладених викликів (у контекстному стеку виконання),а потім виводить їх.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,8 @@ importance: 5

---

#Output a single-linked list in the reverse order
#Вивести одинозв’язаний список у зворотному порядку

Output a single-linked list from the previous task<info:task/output-single-linked-list>in the reverse order.
Виведіть одинозв’язаний список з попереднього завдання<info:task/output-single-linked-list>у зворотному порядку.

Make two solutions: using a loop and using a recursion.
Зробіть два рішення: за допомогою циклу та з використанням рекурсії.
Loading

[8]ページ先頭

©2009-2025 Movatter.jp