재귀함수 - CodeState 3주차 3~4일

종종2·2022년 7월 21일
0

codestates BEB

목록 보기
6/14

재귀함수 ?

어떤 문제를 해결할 때, 동일한 구조의 더 작은 문제를 해결함으로써 주어진 문제를 해결하는 방법

재귀가 적합한경우

1. 주어진 문제를 비슷한 구조의 더 작은 문제로 나눌 수 있는 경우
2. 중첩된 반복문이 많거나 반복문의 중첩횟수를 예측하기 어려운 경우

재귀함수를 사용한다면, 간결하고 일부는 이해하기도 쉬워진다.


재귀적 사고 예제)
5! = 5x4x3x2x1 여기서 더 작은 문제로 쪼갤 수 있다
5! = 5x4!로
5! = 5x4x3!로 점점 작은 단위로 쪼갤 수 있다. 이러한 형식을 재귀적 사고로 해결할 수 있다.

function fac(n){
if(n==1) { return 1;}

return n*fac(n-1);

}

💥주의

재귀함수를 구성할 때에는 탈출조건을 명시해주는 것이 좋다.
재귀를 지정해야해주는 범위도 우리가 지정해줘야함.

  • 쪼갤 수 없는 경우에 무엇을 리턴해야하는 지 생각
  • 쪼갤 수 있는 경우에 recursive case로 반복

재귀의 장점 및 단점

장점

  • 알고리즘이 재귀로 표현하기에 자연스러울 경우, 프로그램의 가독성이 좋아진다.

단점

  • 값이 리턴되기 전에 호출마다 callstack을 새로 생성하므로, 메모리를 많이 사용한다.

나의 이해?

재귀함수는 맨앞을 기준으로 항상 뒤를 쪼갠다.
기준(맨앞)| 뒤--> 뒤에서 다시 재귀
기준(맨앞)|기준(맨앞)|뒤 이런식으로 점점 쪼갠다.
이러한 논리로 재귀를 이해했다.

JSON

Javscript Object Notation의 줄임말로 데이터 교환을 위해 만들어진 객체 형태의 포맷

메시지 객체를 전송하려면

1. 수신자와 발신자가 같은 프로그램을 사용한다.
2. 문자열처럼 범용적으로 읽을 수 있어야한다.

💥 주의

객체는 타입 변환을 이용해 String으로 변환한다면, 객체의 내용을 포함하지 않는다

toString()과 String() 메소드를 사용하면 [object object]로 반환한다.

🚩 해결방법

JSON형태로 변환하거나, JSON을 객체의 형태로 변환한다.

  • JSON.stringfy() : Object를 JSON으로 변환
  • JSON.parse : JSON을 Object로 변환

❗❗ JSON으로 변환된 객체의 타입은 문자열이다.

stringfy(serialize : 직렬화)
parse(deserialize : 역직렬화)


이후 sprint를 진행하면서 재귀에 대한 실습을 진행하였고, JSON과 DOM을 조작하여 DOM tree 구조에 대한 이해를 진행하였다.

진행 시 오류 상태 (stringfy.JSON.js [sprint])

빈 문자열 안에 stringfy를 통해 객체를 JSON화로 문자열로 변환해주는 과정에서
slice 메소드를 사용하는 과정이 있었는데,
슬라이스한 상태를 담지않고, 그대로 쓰는데,
console.log로 확인해본결과 배열의 형태로 변한것이아니라

해결방법?

  1. slice()는 얕은복사이므로 사본을 만들지 않고, 원본을 참조하도록 복사한 척을 한다. 그러므로 참조 값을 만들어줘야한다.

진행 시 오류 상태 (tree-ui[sprint])

객체 안에 children이 없는 경우와 children이 있는 경우를 나타내주었고, 재귀적으로 children이 있는 경우에 ul안에 children 들을 재귀적으로 li로 연결해주었다.
하지만, 원래 원하던 결과와 다른 결과가 나왔다.

틀린 결과

원래 원하던 결과

원래결과

해결방법

children이 없는 경우를 먼저 조건문으로 해줘야한다.
왜냐하면, children이 있는 경우, ul태그를 만들어서 그 안에 li태그를 재귀적으로 함수로 호출해서 만들어서 ul 태그에 붙인다. (이 때 ul태그로 현재 currentNode를 옮긴상태)
하지만, children이 있는경우를 먼저 선언해주고, children이 없는 경우를 뒤늦게 조건을 해준다면, 위처럼 원하지 않는 결과처럼 또 li가 만들어진다. 이유는 , currentNode를 ul로 바꾸었기 때문이다.
children이 없는 경우, root 노드에 바로 갖다 붙여야하는데, 뒤늦게 children이 있는 경우 뒤에 children이 없는 경우를 만든다면, 현재 위치 currentNode가 ul인 밑에 li를 붙이게된다.

그래서 결론은 children이 없는 경우를 먼저 생각해줘야한다.

참고 및 추가 공부

  1. 얕은복사 vs 깊은복사

  2. for of, forEach, for in

  3. 코플릿 13,14,15

profile
나 이현종

0개의 댓글