문제를 동일한 구조의 더 작은 문제로 나누고, 이 작은 문제를 해결함으로써 전체 문제를 해결하는 방법을 재귀(recursion)라고 한다.
자연수로 이루어진 배열을 입력받고 리스트의 합을 리턴하는 함수를 작성해보려고 한다. 나는 기존에 배웠던 반복문과 reduce 메소드를 떠올렸다. 여기에 재귀를 적용해본다면?
arrSum([]) = 0; // what's the simplest input?
arrSum([2]) = 2 + arrSum([]) = 2;
arrSum([6, 2]) = 6 + arrSum([2]) = 6 + 2 = 8;
arrSum([8, 6, 2]) = 8 + arrSum([6, 2]) = 8 + 8 = 16;
//...
arrSum(arr) = arr[0] + arrSum(arr.slice(1));
재귀호출
이라고 한다. 재귀 함수의 입력값과 출력값 정의하기
arrSum: [number] => number
문제를 쪼개고 경우의 수를 나누기
단순한 문제 해결하기
base case
: 가장 해결하기 쉬운 재귀의 기초부터 해결한다. 이는 재귀 호출이 멈추는 조건을 구성한다. (재귀의 탈출 조건)남은 복잡한 문제 해결하기
arrSum([e1, e2, ... , en]) = e1 + arrSum([e2, ..., en])
코드로 구현하기
function arrSum(arr) {
// base case
if (arr.length === 0) {
return 0;
}
// recursive case
return arr[0] + arrSum(arr.slice(1));
// head + arrSum(tail) 배열의 첫 요소와 첫 요소가 제거된 나머지 요소
}
===재귀 템플릿===
function recursive(input1, input2, ...) {
// base case
if (문제를 더 이상 쪼갤 수 없을 경우) {
return 단순한 문제의 해답;
}
// recursive case
return 더 작은 문제로 새롭게 정의된 문제
}
function fac(n) {
if(n === 1) {
return 1;
}
return n * fac(n-1);
}
JSON은 JavaScript Object Notation의 줄임말로, 서로 다른 프로그램에서 데이터 교환을 위해 만들어진 객체 형태의 포맷이다.
메세지 객체를 전달하고 싶다면, 수/발신자가 같은 프로그램을 사용하거나 범용적인 문자열로 처리되어야 한다. 하지만 문제가 있다. 사용자가 서로 다른 프로그램을 사용한다면? 혹은 문자열 처리를 하기 위해 toString()이나 형변환을 시도하면 객체의 내용이 포함되지 않는다.
그래서 JSON을 사용한다.
JSON.stringify(message)
: 직렬화(serialize), 타입은 문자열
JSON.parse(packet)
: 역직렬화(deserialize), 타입은 객체
=> 서로 정반대의 작업을 수행한다.
let packet = `{"sender":"수리","receiver":"골똥","message":"러닝하자!","createdAt":"2021-12-12 10:10:10"}`
console.log(typeof(packet))
// 'string'
let obj = JSON.parse(packet)
console.log(obj)
/*
* {
* sender: "수리",
* receiver: "골똥",
* message: "러닝하자!",
* createdAt: "2021-12-12 10:10:10"
* }
*/
console.log(typeof(obj))
// `object`
그림을 보면 fib(5)를 구하기 위해 fib(3)이 두 번 평가되는 걸 볼 수 있다. 함수 호출 도중에 수많은 서브 호출이 일어난다. 같은 값들이 여러 번 평가된다. 그럼 어떻게 해결할까?