-정의
동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술(동적 계획법의 핵심이 되는 기술)
// Q. 피보나치 수열 중 n번째 항의 수를 리턴
// 입출력 예시
output = fibonacci(5);
console.log(output); // --> 5
// A.
let fibonacci = function (n) {
const memo = [0, 1];
const aux = (n) => {
// 이미 해결한 적이 있으면, 메모해둔 정답을 리턴한다.
if (memo[n] !== undefined) return memo[n];
// 새롭게 풀어야하는 경우, 문제를 풀고 메모해둔다.
memo[n] = aux(n - 1) + aux(n - 2);
return memo[n];
};
return aux(n);
};
// aux 함수 -> ✅재귀 함수 ✅클로저 함수
// aux 함수 내부에서 aux 함수를 호출하므로 재귀함수
// aux 함수가 외부 함수에 의해 리턴되고 있고, 외부 함수의 변수(memo)가 aux 함수 내부에서 사용되므로 클로저 함수
-참고: 클로저, 커링
클로저: 함수 + 함수가 선언된 어휘적 환경
클로저 함수: 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수
커링: 다중 인수를 갖는 함수를 단일 인수를 갖는 함수들의 함수열로 바꾸는 것(기술)(ex. sum(a, b, c)을 sum(a)(b)(c)으로 변환)
참고 사이트: https://ko.javascript.info/currying-partials
약수: 어떤 수를 나누어떨어지게 하는 수
소수: 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수
(i는 1부터 num까지)
num % i === 0 -> 약수
1 -> 소수 아님
2 -> 소수
짝수 -> 소수 아님
(반복문 적용)3이상의 홀수 중 3, 5, 7, ... Math.sqrt(n)로 나눠어지지 않는 수 -> 소수
// 신기한 풀이: 소수 개수
function solution(nums) {
const prime = new Array(nums+1).fill(1);
let count = nums-1;
for (let i=2; i<Math.sqrt(nums); i++) {
if (prime[i]) {
for (let j=i**2; j<=nums; j+=i) {
if (prime[j]) {
count--;
prime[j]=0;
}
}
}
}
return count;
}
출처: https://school.programmers.co.kr/questions/44090
break: 반복문 종료
continue: 한 턴만 넘김
중첩 반복문(이중 for문)일 경우 -> 현재 위치한 가장 안쪽의 반복문에 적용
원본을 바꾸어 정렬
-> 자동 오름차순 정렬
// 내 코드
function solution(emergency) {
// array -> array
// 내림차순 정렬한 새로운 배열 생성
// 원래 배열의 i번째 인덱스 요소를 새로운 배열에서 찾음
// 새로운 배열의 인덱스 + 1을 순서로 설정
// 빈 배열에 순서를 push
let result = []
let sortedEmergency = emergency.slice().sort((a, b) => b - a) //[76,24,3]
for(i = 0; i < emergency.length; i++) {
let order = Number(sortedEmergency.findIndex((el) => {return el === emergency[i]})) + 1
result.push(order)
}
return result
}
let [a, b] = str.split()으로 바로 할당 가능
더하기: a 1
빼기: a (-1)
각 자리수가 같을 때만 0
const a = 5; // 101
const b = 3; // 11
console.log(a ^ b) // 6(=110)
숫자1 = 숫자 1 ^ 숫자2
는 숫자1 ^= 숫자2
로 축약해서 쓸 수 있음
let a = 5; // 101
a ^= 3; // 11
console.log(a); // 6(=110)
let arr = [5, 3] // [101, 11]
arr[0] ^= arr[1] // arr[0] = 110 -> [110, 11]
arr[1] ^= arr[0] // arr[1] = 101 -> [110, 101]
arr[0] ^= arr[1] // arr[0] = 11 -> [11, 101]
console.log(arr) // [3, 5]
-가능한 이유
101, 110, 011 중 어떤 두 수를 선택해 XOR 연산을 시켜도 항상 나머지 한 수가 나오기 때문(트리오)
let temp = arr[idx1];
arr[idx1] = arr[idx2];
arr[idx2] = temp;
[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]];
arr[idx1] ^= arr[idx2];
arr[idx2] ^= arr[idx1];
arr[idx1] ^= arr[idx2];
// 전개연산자 활용
const arr = ['A', 'B', 'C', 'A', 'B'];
const set = new Set(arr);
const newArr = [...set];
console.log(newArr) // [ 'A', 'B', 'C' ]
// Array.from 활용
const arr = ['A', 'B', 'C', 'A', 'B'];
const newArr = Array.from(new Set(arr));
console.log(newArr) // [ 'A', 'B', 'C' ]
// Set.prototype.size
const arr = ['A', 'B', 'C', 'A', 'B'];
const setSize = (new Set(arr)).size;
console.log(setSize) // 3
Object.keys(객체) -> key를 요소로한 배열 반환
Object.values(객체) -> value를 요소로한 배열 반환
+()로 쓸 수 있음