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.
