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

JavaScript에서 연속 요소의 합을 기준으로 배열을 2차원 배열로 분할하는 방법

숫자로 이루어진 배열과 숫자 n을 인수로 받는 함수를 작성해야 한다고 가정해 보겠습니다. 이때 n은 배열의 어떤 요소보다 크거나 같아야 합니다. 이 함수는 배열에서 연속된 요소들의 합이 n을 초과하는 지점마다 배열을 잘라서 여러 개의 하위 배열(subarray)로 분할해야 합니다.

문제 이해하기

예를 들어 다음과 같습니다.

// 원본 배열:
const arr = [2, 1, 2, 1, 1, 1, 1, 1];
// 숫자 n이 4일 때
// 기대되는 출력 결과:
const output = [ [ 2, 1 ], [ 2, 1, 1 ], [ 1, 1, 1 ] ];

위 예제에서 첫 번째 하위 배열 [2, 1]의 합은 3입니다. 여기에 다음 요소 2를 더하면 5가 되어 n(4)을 초과하므로 새로운 하위 배열이 시작됩니다. 이런 방식으로 전체 배열이 조건에 맞게 분할됩니다.

구현 코드

이 함수는 reduce() 메서드를 활용하면 간결하게 구현할 수 있습니다. 누적값(acc) 안에 현재까지의 합(sum)과 결과 배열(res)을 함께 관리하는 것이 핵심입니다.

const arr = [2, 1, 2, 1, 1, 1, 1, 1];
const splitArray = (arr, num) => {
    return arr.reduce((acc, val, ind) => {
        let { sum, res } = acc;
        // 첫 번째 요소인 경우 새로운 하위 배열 생성
        if(ind === 0){
            return {sum: val, res:[[val]]};
        };
        // 현재 합계에 요소를 더해도 num 이하라면 기존 배열에 추가
        if(sum + val <= num){
            res[res.length-1].push(val);
            sum += val;
        }else{
            // 초과한다면 새로운 하위 배열 시작
            res.push([val]);
            sum = val;
        };
        return { sum, res };
    }, {
        sum: 0,
        res: []
    }).res;
};
console.log(splitArray(arr, 4));
console.log(splitArray(arr, 5));

코드 동작 방식

  1. 초기화: reduce의 초기 누적값으로 sum(현재 부분 배열의 합)과 res(결과 배열)를 설정합니다.
  2. 첫 번째 요소 처리: 인덱스가 0일 경우, 해당 값을 포함한 새로운 하위 배열을 만들고 sum을 초기화합니다.
  3. 합계 판단: 현재 값(val)을 더했을 때 num 이하라면 마지막 하위 배열에 값을 추가하고, 그렇지 않으면 새로운 하위 배열을 생성합니다.
  4. 결과 반환: 모든 요소를 순회한 후 최종적으로 res만 반환합니다.

출력 결과

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

[ [ 2, 1 ], [ 2, 1, 1 ], [ 1, 1, 1 ] ]
[ [ 2, 1, 2 ], [ 1, 1, 1, 1, 1 ] ]

n이 4일 때와 5일 때 각각 다른 방식으로 배열이 분할되는 것을 확인할 수 있습니다. 이 알고리즘은 배열을 한 번만 순회하므로 시간 복잡도가 O(n)으로 매우 효율적이며, 비용 계산, 페이지네이션, 배치(batch) 처리 등 실무에서도 유용하게 활용할 수 있습니다.