TIL Day-25


25日目


2020年の最終日になりました.
もし誰かがこの文章を読んでいたら
来年できることがすべて成功することを望みます.
最終日だったので12時まで寝ないといけないと思いました
実は昨夜私がベッドに横になったのは11時半ぐらいでした.
夜明けに急にお腹が痛くてよく眠れなかった.
最後にベッドで時計を見たのは朝6時半くらいでした.
そのまま1時間半寝て、今でも目が覚めています.
でも12時まで頑張らなきゃ

新学の品


さいきかんすう


は、関数を再使用することです.
function sumTo(num) {
  if(num <= 1) {
    return num
  }
  return num + sumTo(num - 1)
  
}
上の関数は
ある関数は、その数に次の数を加えた値を返します.
だいたいこんな感じです.
sumTo(4) = 1 + 2 + 3 + 4 = 10
再帰関数の駆動過程をさらによく観察すると,このことが分かった.
function sumTo(4) {
  if(4 <= 1) {
    return 4
  }
  return 4 + sumTo(3) { // 4 + 6 = 10
    if(3 <= 1) {
      return 3
    }
    return 3 + sumTo(2) { // 3 + 3 = 6
      if(2 <= 1) {
        return 2
      }
      return 2 + sumTo(1) { // 2 + 1 = 3
        if(1 <= 1) {
          return 1 // sumTo(1) = 1
        }
} 
再帰関数により、同じ関数を呼び出し続けることがわかります.
呼び出された関数は呼び出されるのを待つ
非同期処理を行うことに相当する.
また、再帰関数を使用すると、重複文を使用するよりも使用します.
より短いコードを書くことができます.
// 반복문을 사용해 작성한 함수
function factorial(n) {
  let result = 1;
  for (let 1 = n; i > 0; i--) {
    result = result * i;
  }
  return result;
}
// 재귀함수를 사용해 작성한 함수
function factorial(n) {
  if(n === 0) {
    return 1;
  }
  return n * factorial(n - 1);
}
同じ作業を行う関数である2つのコードを比較します.
繰り返し文を使用する関数には、タイプの違いがたくさんあるように見えます.
この再帰関数はどのように書くべきですか.

再帰関数の使い方


問題が発生した場合、何を受け取るか、どのように出力するか
決定から始めたほうがいい.
例えば、数値からなる配列を入力し、
もし再び数字に戻るならどう表現しますか?
  • arrSum: [number] -> number
  • このように表現できるかもしれません.
    このように印刷する必要がある場合は、次の条件に従います.
    問題を解決するかどうか考えなければなりません.
    このとき重要な観点は順序と大きさである.
    指定された入力値に基づいて区別できます.
    順番が決められるかどうか見てみましょう.
    arrSumでは,入力値配列の大きさによって区別できる.arrSum([1, 2, 3, 4])arrSum([2, 3, 4])
    大きさを求める方法が同じであることを知っています.
    もしそうなら、いくつかの条件を提示できるはずです.
  • arrSum入力値が空配列と非空配列に分けられる.
  • arrSum: [number] -> number
  • arrSum([])
  • arrSum([e1, e2, ..., en])
  • このように問題を分け終わったら,まず最も容易な問題を解決する.
    このように解決した問題を再帰の基礎と呼ぶ.
    再帰の基礎は再帰関数を実現する際の再帰の脱出条件である.
  • arrSum入力値が空の配列arrSum = 0はい
  • arrSum: [number] -> number
  • arrSum([])
  • arrSum([e1, e2, ..., en])
  • 今、もっと複雑な問題を解決しましょう.
  • arrSum入力長が1より大きい配列
    一番前の要素も求めます.
    (配列の一番前の要素なのでheadと名付けられました.)
    残りの要素を新しい入力値として使用する問題が解決しました.
    得られた結果はhead
  • arrSum: [number] -> number arrSum([]) arrSum([e1, e2, ..., en]) = e1 + arrSum([e2, ..., en])

  • 配列時に区分head残りの部分(tail)のみを知っていれば解決arrSum
  • このように分割する問題をコードで以下のように実現する.
    function arrSum(arr) {
    // 재귀의 기초 (base case)
    // 문제를 더 이상 쪼갤 수 없을 경우
    if (arr의 길이가 0인 경우) {
        return 0;
    }
    // recursive Case
    // 그렇지 않은 경우
    // head: 배열의 첫 요소
    // tail: 배열의 첫 요소만 제거된 배열
    return head + arrSum(tail);
    }
    このような構成は再帰的なテンプレートと見なすことができる.
    これを利用して再帰関数で様々な問題を解決する方法を練習します