Udemy - 재귀 심화문제


Untitled

Untitled 1

허허….😅


1️⃣  reverse ( 거꾸로 출력하기 )

입력된 String을 거꾸로 출력하는 재귀함수 알고리즘을 작성!

1
2
3
4
5
6
7
8
9
function reverse(input) {
// 1. Endpoint 조건 작성
// input의 length가 1에 닿으면 -> 그 하나 남은 값을 출력하면 된다.
if (input.length < 2) {
return input[input.length - 1];
}
// 2. input의 가장 끝 값을 잘라나가면서 String에 붙여준다.
return input[input.length - 1] + reverse(input.slice(0, -1));
}

2️⃣  isPalindrome ( 앞뒤가 똑같은 단어 찾기 )

주어진 String 입력값이 앞뒤로 반전을 해도 같은 단어라면 true를, 아니라면 false를 출력하는 재귀 함수 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function isPalindrome(input) {
// 1. Endpoint 작성
// 1-1. input.length가 짝수인 경우 마지막 단계에서 두 개의 char가 남는다.
if (input.length === 2) {
return input[0] === input[1];
// 하지만, 홀수인 경우 마지막에 하나의 char만 남으므로, 이는 뒤집어도 가운데에 위치하기에 true를 반환해주면 된다.
} else if (input.length === 1) {
return true;
}
// 2. 재귀함수 실행 (&&을 사용하면 하나라도 false일 시에, false가 반환됨)
return (
input[0] === input[input.length - 1] && isPalindrome(input.slice(1, -1))
);
}

3️⃣  someRecursive ( 하나라도 만족하는가? )

주어진 배열 입력값 중에, 주어진 조건을 하나라도 충족하면 true를, 아니면 false를 출력하는 재귀함수 알고리즘을 작성하시오

1
2
3
4
5
6
7
8
9
10
11
12
function someRecursive(arr, callback) {
// 만약 arr.length가 0이 될 때까지 true가 반환되지 않았다면, false를 반환해주면 된다.
if (arr.length === 0) {
return false;
}
// callback(arr[0])의 값이 true면 true를 반환한다.
if (callback(arr[0])) {
return true;
}
// 위 두 조건을 모두 만족시키지 못한다면 배열을 잘라나가며 재귀함수를 실행시킨다.
return someRecursive(arr.slice(1), callback);
}

4️⃣  flatten ( 중첩 배열 풀어내기 )

[ [ ], [ [ ] ]] 와 같은 중첩 배열들을 하나의 배열로 풀어서 반환하는 재귀함수 알고리즘을 작성하시오

  • 나의 솔루션
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 뭐가 문제인지는 모르겠으나... 나의 솔루션은 계속 알 수 없는 오류가 난다.
    function flatten(arr) {
    // 새로운 배열을 반환해야 한다고 했으니 일단 newArr에 담아준다.
    let newArr = arr;
    // 만약 모든 요소 중 어떤 것도 배열이 아니라면? => 해당 newArr 반환
    if (!newArr.some((el) => Array.isArray(el))) {
    return newArr;
    }
    // 위의 조건 통과하지 못하면 -> newArr를 flat해서 다시 재귀
    return flatten(newArr.flat());
    }
  • 제시된 솔루션
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function flatten(oldArr) {
    let newArr = [];
    for (let i = 0; i < oldArr.length; i++) {
    if (Array.isArray(oldArr[i])) {
    // 여기서는 concat을 사용했다.
    // concat 안에서 재귀가 이뤄진다.
    newArr = newArr.concat(flatten(oldArr[i]));
    } else {
    newArr.push(oldArr[i]);
    }
    }
    return newArr;
    }

5️⃣  capitalizeFirst ( 첫 글자 대문자로 바꾸기 )

주어진 배열 내의 String들의 첫 글자를 대문자로 바꾸는 재귀함수 알고리즘을 작성하시오

  1. 아스키 코드 (10진수)
    • A-Z : 65~90
    • a-z : 97~122
1
2
3
4
5
6
7
8
9
10
11
12
function capitalizeFirst(arr) {
// 만약 arr.length가 1에 닿으면 -> 첫 글자 대문자로 치환 + 나머지 글자 합친 것 return
if (arr.length === 1) {
return [arr[0][0].toUpperCase() + arr[0].slice(1)];
}
// 위 조건 충족하지 못하면
// 첫 글자 대문자로 치환 + 뒷 글자들 붙임, 뒤의 나머지 배열 요소들 또한 재귀를 통해 첫글자 대문자화
return [
arr[0][0].toUpperCase() + arr[0].slice(1),
...capitalizeFirst(arr.slice(1)),
];
}

6️⃣  nestedEvenSum

nested 오브젝트 내에 존재하는 모든 짝수 value들의 합을 구하는 재귀함수 알고리즘을 작성하시오

  • 주어진 object 1과 2
    주어진 object 1과 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// typeOf Object를 활용하면 될 것 같다.
function nestedEvenSum(obj, sum = 0) {
// for ... in 반복문을 통해 오브젝트의 key값들을 활용
for (let key in obj) {
// key = 오브젝트의 key
// 만약 key의 value의 타입이 object라면 재귀 대상
if (typeof obj[key] === 'object') {
// 이렇게 해당 오브젝트가 함수에의해 다시 들어가면 for문에 의해 계속 벗겨질 것
sum += nestedEvenSum(obj[key]);
// 만약 해당 key의 value가 숫자이고, 짝수라면? -> sum에 그 값을 더해주기
} else if (typeof obj[key] === 'number' && obj[key] % 2 === 0) {
sum += obj[key];
}
}
return sum;
}

7️⃣  capitalizeWords (모든 문자 대문자화)

배열에 담긴 모든 문자열들을 대문자로 치환하는 재귀함수 알고리즘을 작성하시오

Untitled 3

1
2
3
4
5
6
function capitalizeWords(arr) {
if (arr.length === 1) {
return [arr[0].toUpperCase()];
}
return [arr[0].toUpperCase(), ...capitalizeWords(arr.slice(1))];
}

8️⃣  stringifyNumbers

nestedObject의 values들 중에 ‘숫자’인 값들을 찾아서 모두 stringify하여 반환하는 재귀함수 알고리즘을 작성하시오

Untitled 4

Untitled 5

💡 Array를 typeof를 통해 검사하면 ‘object’가 반환된다는 것을 처음 알았다….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 처음엔 그냥 기존 obj를 수정하는 방식으로 했는데, TDD에서 원본 오브젝트는 건들지 말란다...
// 그래서 newObj={}라는 입력값을 추가했음
function stringifyNumbers(obj, newObj = {}) {
// obj에 대한 for문을 돌린다.
for (let key in obj) {
// 만약 해당 value가 오브젝트이고, 배열이 아니라면 -> 재귀 대상
if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
// newObj의 해당 key값의 value는 수정된 object가 된다.
newObj[key] = stringifyNumbers(obj[key]);
} else if (typeof obj[key] === 'number') {
newObj[key] = obj[key].toString();
} else {
// 여기는 value가 오브젝트도 아니고, 숫자도 아닐 경우 -> 그냥 그대로 newObj에 넣음
newObj[key] = obj[key];
}
}
return newObj;
}

9️⃣  collectStrings ( String만 모으기 )

주어진 nestedObject 안에서 String Value값들만을 한 배열에 모아서 반환하는
재귀함수 알고리즘을 작성하시오

Untitled 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 최종 리턴할 배열을 arr=[]와 같이 입력해줬다.
function collectStrings(object, arr = []) {
for (let key in object) {
// object면? -> 스프레드 연산하여 arr에 담아준다
// 재귀가 되며 지속적으로 object 속을 탐색한다.
if (typeof object[key] === 'object') {
arr.push(...collectStrings(object[key]));
// value가 string인 것이 발견되면 arr에 푸시한다
} else if (typeof object[key] === 'string') {
arr.push(object[key]);
}
}
return arr;
}

Author

Hoonjoo

Posted on

2022-01-10

Updated on

2022-02-07

Licensed under

Comments