Skip to content

Conversation

@memeseo
Copy link

@memeseo memeseo commented Jul 16, 2024

재귀적 사고로 생각하는 게 어려웠지만 반복해서 하다보니 어느정도 감을 잡은 거 같아요!

Comment on lines 2 to 5
const solution1 = (numbers) => {
if(numbers?.length === 0) return 0;

return numbers.reduce((acc, cur) => acc + cur, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

numbers가 주어지지 않아서 undefined이거나 null로 주어진 경우를 처리하기 위해서 옵셔널 체이닝을 사용하셨네요.

만약 주어지지 않았다면 numbers?.length는 undefined일 것이고, 0이랑 비교했을 때 참이 아니기 때문에 0으로 리턴되지 않습니다. 그리고 나서 reduce 메서드를 실행할탠데 이때 undefined이기 때문에 아마도 이런 에러가 발생할 것입니다.

Uncaught TypeError: Cannot read properties of undefined (reading 'reduce')

이런 경우를 위해서라면 기본값을 주는 방법으로 해결할 수 있겠습니다.

const solution1 = (numbers = []) => {
  if(numbers.length === 0) return 0;

  return numbers.reduce((acc, cur) => acc + cur, 0);
}

이러면 numbers가 주어지지 않은 경우 numbers는 빈 배열이 되고 길이가 0이기 떄문에 0으로 빠르게 종료됩니다.

근데 사실 reduce메서드는 기본값이 주어진 경우 빈 배열에 실행해도 같은 결과가 나옵니다.

const solution1 = (numbers = []) => numbers.reduce((acc, cur) => acc + cur, 0); 

따라서 위와 같이 할 수 있습니다.

reduce는 기본값이 주어지지 않은 경우에는 배열이 비어있으면 에러가 나지만, 기본값이 주어진 경우에는 비어있으면 기본값을 그대로 반환합니다.

const solution1 = (numbers) => {
if(numbers?.length === 0) return 0;

return numbers.reduce((acc, cur) => acc + cur, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

강의에서 따로 설명하진 않았지만, 꼬리 재귀 문제는 모두 reduce로 변환할 수 있고, reduce는 모두 꼬리 재귀로 변환할 수 있습니다. 두 가지 동작하는 방식을 생각해보면 사실 똑같이 생겼죠

Comment on lines 9 to 14
// Maximum call stack size exceeded 오류나는데 왜 나는지 모르겠습니다
const solution2 = (numbers) => {
if(numbers?.length === 0) return 0;

return numbers[0] + solution2(numbers.slice(1));
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

충분히 numbers로 이 함수를 실행하게 되면 너무 많은 스택이 생겨서 예외가 발생합니다. 예를들어서 [1, 2, 3, ... , 10000000] 이 주어졌다면, 처음에 함수 호출은 return 1 + solution2([2, 3, ... , 10000000])를 반환할 것입니다. 근데 리턴을 하려면 아직 새로운 solution2실행 함수가 끝난 뒤에야 리턴할 수 있기 때문에 콜 스택을 유지한채로 새로운 스택을 만들어서 두 번째 solution2를 실행하게 됩니다. 이런식으로 numbers가 빌때까지 반복하는데요. 자바스크립트 엔진에서 너무 많은 스택을 만들 경우 예외가 발생하도록 되어 있습니다. 그래서 해당 에러가 발생하는 것입니다.

Comment on lines +44 to +45
const remainder = n % 2;
n = Math.floor(n / 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나머지를 remainder로 했다면, 몫은 quotient라는 이름으로 해도 괜찮겠네요

const solution = () => {
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
const solution1 = (binaryString) => {
const array = binaryString.split('').map(Number);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바이너리로 된 문자열을 하나씩 잘라서 map매서드로 숫자로 바꿔주고 있네요. Number는 value하나만 받는 생성자 입니다. 하지만 map의 메서드의 콜백 함수 시그니처는 다음과 같이 생겼습니다.

image

3개의 인자를 전달하고 있죠. 하지만 Number는 하나의 값만 받고 있습니다. 문제는 없지만, 이걸 생각하지 않고 값만 사용하기 위해서 참조만 전달할 경우 문제가 생길 수 있습니다. 대표적으로 parseInt같은게 있죠.

['1', '2', '3', '4', '5'].map(parseInt); // [ 1, NaN, NaN, NaN, NaN ]

그래서 함수 시그니처를 항상 주의깊게 보고 사용하는 것이 좋습니다.

참고

const solution = () => {
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
const solution1 = (binaryString) => {
const array = binaryString.split('').map(Number);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 만약에 입력으로 아주아주 큰 바이너리 문자열이 주어졌다면 어떻게 될까요? 문자열을 한 번에 순회해서 map을 돌아서 아주 큰 배열을 만들겠죠? 컴퓨터가 메모리에 담을 수 없는 엄청 큰 바이너리 문자열이 주어진다면 무슨 일이 벌어질까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스택 오버플로우가 발생할 거 같아요 !

memeseo added 2 commits July 20, 2024 15:27
- numbers 배열 옵셔널 체이닝 > 기본값 설정으로 변경
- 이진수 배열 생성 후 10진수 변환 > parseInt 함수 사용 및 인덱스 위치로 10진수 변환
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants