Sammentæl alle tal op til et bestemt tal
Skriv en funktion sumTo(n) som beregner summen af tallene 1 + 2 + ... + n.
For eksempel:
sumTo(1) = 1
sumTo(2) = 2 + 1 = 3
sumTo(3) = 3 + 2 + 1 = 6
sumTo(4) = 4 + 3 + 2 + 1 = 10
...
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050
Opret tre variationer af løsningen:
- Ved brug af et
for-loop. - Ved brug af rekursion, da
sumTo(n) = n + sumTo(n-1)forn > 1. - Ved brug af formlen Differensrække. Det engelske opslag aritmetisk progression giver en dybere forklaring, hvis du har brug for det.
Her er et eksempel på resultatet:
function sumTo(n) { /*... din kode ... */ }
alert( sumTo(100) ); // 5050
P.S. Hvilken løsning er hurtigst? Og hvilken er langsomst? Hvorfor?
P.P.S. Kan vi bruge rekursion til at regne sumTo(100000)?
Løsningen ved brug af et for-loop:
function sumTo(n) {
let sum = 0;
for (let i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
alert( sumTo(100) );
Løsningen der bruger rekursion:
function sumTo(n) {
if (n == 1) return 1;
return n + sumTo(n - 1);
}
alert( sumTo(100) );
Løsningnen der bruger formlen: sumTo(n) = n*(n+1)/2:
function sumTo(n) {
return n * (n + 1) / 2;
}
alert( sumTo(100) );
P.S. Naturligvis er formlen den hurtigste løsning. Den bruger kun 3 operationer for ethvert tal n. Matematikken hjælper!
Loop-varianten er den anden i hastighed. I både den rekursive og loop-variant summerer vi de samme tal. Men rekursionen involverer indlejrede kald og stak-håndtering. Det tager også ressourcer, så det er langsommere.
P.P.S. Nogle motorer understøtter “tail call” optimering: hvis et rekursivt kald er det sidste i funktionen uden andre beregninger udført, så vil den ydre funktion ikke behøve at genoptage eksekveringen, så motoren behøver ikke at huske dens eksekveringskontekst. Det fjerner byrden på hukommelsen. Men hvis JavaScript-motoren ikke understøtter tail call optimering (de fleste gør ikke), vil der være en fejl: maksimal stakstørrelse overskredet, fordi der normalt er en begrænsning på den totale stakstørrelse.