Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 자기 자신을 제외한 나머지 숫자들의 곱으로 새 배열 만들기

숫자로 이루어진 배열을 인수로 받아, 현재 계산 중인 인덱스를 제외한 나머지 숫자들의 곱을 담은 새로운 배열을 반환하는 함수를 작성해야 한다고 가정해 보겠습니다.

예를 들어, arr에 5개의 인덱스가 있고 인덱스 1의 값을 만든다면, 인덱스 0, 2, 3, 4에 있는 숫자들이 서로 곱해집니다. 마찬가지로 인덱스 2의 값을 만들 때는 인덱스 0, 1, 3, 4의 숫자들을 곱하는 식으로 진행됩니다.

참고 − 배열 안의 모든 요소는 0이 아니라고 보장되어 있습니다.

접근 방법

가장 효율적인 방법은 배열을 두 단계로 처리하는 것입니다.

  • 1단계: reduce() 메서드를 사용해 배열 전체 요소의 곱(총곱)을 한 번에 계산합니다.
  • 2단계: map() 메서드로 배열을 순회하면서, 총곱을 해당 인덱스의 원래 값으로 나눈 값을 새 배열에 담습니다.

자기 자신을 제외한 나머지 숫자들의 곱은 결국 '전체 곱 ÷ 자기 자신'과 같으므로, 나눗셈만으로 각 인덱스의 값을 손쉽게 구할 수 있습니다. 배열을 두 번만 순회하면 되기 때문에 시간 복잡도는 O(n)으로 매우 효율적입니다.

예제 코드

const arr = [12, 10, 8, 6, 5, 2];
const produceArray = (arr) => {
    const product = arr.reduce((acc, val) => acc * val);
    return arr.map(el => {
        return product / el;
    });
};
console.log(produceArray(arr));

출력 결과

콘솔에 출력되는 결과는 다음과 같습니다 −

[ 4800, 5760, 7200, 9600, 11520, 28800 ]

주의할 점

이 방식은 나눗셈을 사용하기 때문에 배열에 0이 포함되어 있으면 InfinityNaN이 발생할 수 있습니다. 따라서 0이 포함될 가능성이 있는 입력이라면, 왼쪽 누적 곱과 오른쪽 누적 곱을 미리 계산해 조합하는 방식(prefix/suffix product)을 사용하는 것이 안전합니다. 본 예제에서는 모든 요소가 0이 아님을 보장하기 때문에 위의 간단한 나눗셈 방식이 그대로 적용 가능합니다.