freeCodeCamp/curriculum/challenges/chinese-traditional/02-javascript-algorithms-an.../basic-javascript/use-recursion-to-create-a-c...

2.9 KiB

id title challengeType forumTopicId dashedName
5cd9a70215d3c4e65518328f 使用遞歸創建一個倒計時 1 305925 use-recursion-to-create-a-countdown

--description--

在上一個挑戰,學習了怎樣用遞歸來代替 for 循環。 現在來學習一個更復雜的函數,函數返回一個從 1 到傳遞給函數的指定數字的連續數字數組。

正如上一個挑戰提到的,會有一個 base case。 base case 告訴遞歸函數什麼時候不在需要調用其自身。 這是簡單 情況,返回得到的值。 還有 recursive call,繼續用不同的參數調用自身。 如果函數無誤,一直執行直到 base case 爲止。

比如,如果想寫一個遞歸函數,返回一個數字 1n 的連續數組。 這個函數需要接收一個參數 n 代表最終數字。 然後會持續的調用自身,傳入一個比 n 更小的值一直到傳入的值是 1 爲止。 函數如下:

function countup(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray = countup(n - 1);
    countArray.push(n);
    return countArray;
  }
}
console.log(countup(5));

[1, 2, 3, 4, 5] 將顯示在控制檯中。

起初,這似乎是違反直覺的,因爲 n 的值遞減,但是最終數組中的值卻遞增。 之所以發生這種情況,是因爲在遞歸調用返回之後,才調用 push。 在將 n pushed 進數組時,countup(n - 1) 已經調用賦值成功並返回了 [1, 2, ..., n - 1]

--instructions--

已經定義了一個函數 countdown,函數有一個參數(n)。 函數應該基於參數 n 遞歸調用返回 n1 的連續數字的數組。 如果函數以小於 1 的參數調用,函數應該返回空數組。 比如,用 n = 5 調用函數應該返回數組 [5, 4, 3, 2, 1]。 函數必需使用遞歸函數調用自身,不能使用任何形式的循環。

--hints--

countdown(-1) 應該返回一個空數組。

assert.isEmpty(countdown(-1));

countdown(10) 應該返回 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

assert.deepStrictEqual(countdown(10), [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);

countdown(5) 應該返回 [5, 4, 3, 2, 1]

assert.deepStrictEqual(countdown(5), [5, 4, 3, 2, 1]);

代碼不能包含任意形式的循環(forwhile 或者高階函數如:forEachmapfilter 以及 reduce)。

assert(
  !code.match(/for|while|forEach|map|filter|reduce/g)
);

應該用遞歸解決這個問題。

assert(
  countdown.toString().match(/countdown\s*\(.+\)/)
);

--seed--

--seed-contents--

// Only change code below this line
function countdown(n){
  return;
}
// Only change code above this line

--solutions--

function countdown(n){
   return n < 1 ? [] : [n].concat(countdown(n - 1));
}