문제 소개
이번 글에서 다룰 문제는 공백으로 구분된 여러 개의 숫자가 담긴 문자열을 입력받아, 그중 가장 큰 숫자와 가장 작은 숫자를 찾아 공백으로 구분된 하나의 문자열로 반환하는 JavaScript 함수를 작성하는 것입니다.
예를 들어 입력 문자열과 기대되는 출력은 다음과 같습니다.
입력 예시
const str = '5 57 23 23 7 2 78 6';
출력 예시
const output = '78 2';
78이 문자열 내에서 가장 큰 숫자이고, 2가 가장 작은 숫자이기 때문입니다.
해결 방법
이 문제는 다음과 같은 단계로 해결할 수 있습니다.
split(' ')메서드를 사용해 문자열을 공백 기준으로 나누어 배열로 만듭니다.reduce()메서드를 활용해 배열을 순회하면서 최댓값과 최솟값을 동시에 추적합니다.- 초기값으로 각각
-Infinity와Infinity를 설정하여 어떤 숫자와도 비교 가능하도록 합니다. - 템플릿 리터럴을 이용해 결과를 "최댓값 최솟값" 형태의 문자열로 반환합니다.
구현 코드
다음은 위 로직을 구현한 전체 코드입니다.
const str = '5 57 23 23 7 2 78 6';
const pickGreatestAndSmallest = (str = '') => {
const strArr = str.split(' ');
let creds = strArr.reduce((acc, val) => {
let { greatest, smallest } = acc;
greatest = Math.max(val, greatest);
smallest = Math.min(val, smallest);
return { greatest, smallest };
}, {
greatest: -Infinity,
smallest: Infinity
});
return `${creds.greatest} ${creds.smallest}`;
};
console.log(pickGreatestAndSmallest(str));실행 결과
78 2
코드 설명
reduce() 메서드는 배열의 각 요소를 순차적으로 처리하며 누적값(accumulator)을 업데이트합니다. 이 코드에서는 누적값으로 greatest(최댓값)와 smallest(최솟값) 두 속성을 가진 객체를 사용합니다.
Math.max(val, greatest): 현재 값과 지금까지의 최댓값 중 더 큰 값을 선택합니다.Math.min(val, smallest): 현재 값과 지금까지의 최솟값 중 더 작은 값을 선택합니다.
모든 요소의 순회가 끝나면 객체에는 문자열 전체의 최댓값과 최솟값이 저장되어 있으며, 이를 템플릿 리터럴로 조합해 원하는 형식의 문자열을 반환합니다.
마무리
이처럼 split(), reduce(), Math.max(), Math.min()을 조합하면 별도의 정렬 없이도 한 번의 순회로 최댓값과 최솟값을 효율적으로 찾을 수 있습니다. 시간 복잡도는 O(n)으로, 정렬 방식(O(n log n))보다 성능 면에서 유리합니다.