Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ transform_inclusive_scan() 함수 완벽 이해하기

이번 튜토리얼에서는 C++의 transform_inclusive_scan() 함수에 대해 자세히 알아보겠습니다.

transform_inclusive_scan() 함수란?

transform_inclusive_scan()은 C++17부터 <numeric> 헤더에서 제공하는 알고리즘으로, 컨테이너의 각 요소에 단항 연산(unary operation)을 먼저 적용한 뒤, 그 결과들을 이진 연산(binary operation)으로 순차적으로 누적하는 기능을 수행합니다.

결과적으로 각 위치에는 '현재 요소까지의 변환된 누적 값'이 저장됩니다. 흔히 알고 있는 접두사 합(prefix sum)에 변환 단계가 추가된 형태라고 이해하면 쉽습니다. 아래 예제에서는 이 함수를 직접 구현하여 내부 동작 원리를 확인해 보겠습니다.

예제 코드

#include <iostream>
#include <vector>
using namespace std;

namespace point_input_iterator {
    template <class InputItrator, class OutputItrator, class BinaryOperation, class UnaryOperation>
    OutputItrator transform_inclusive_scan(InputItrator first, 
        InputItrator last,
        OutputItrator d_first,
        BinaryOperation binary_op,
        UnaryOperation unary_op){

        *d_first = unary_op(*first);
        first++;
        d_first++;
        for (auto it = first; it != last; it++) {
            // 접두사 합 계산
            *d_first = binary_op(unary_op(*it), *(d_first - 1));
            d_first++;
        }
        return d_first;
    }
}

int main(){
    // 벡터를 사용하여 요소 입력
    vector<int> InputVector{ 11, 22, 33, 44, 55, 66, 77, 88 };
    vector<int> OutputVector(8);

    point_input_iterator::transform_inclusive_scan(
        InputVector.begin(), InputVector.end(), OutputVector.begin(),
        [](auto xx, auto yy) {
            return xx + yy;
        },
        [](auto xx) {
            return xx * xx;
        });

    for (auto item : OutputVector) {
        // 출력 항목 출력
        cout << item << " ";
    }
    cout << std::endl;

    return 0;
}

실행 결과

121 605 1694 3630 6655 11011 16940 24684

동작 원리 분석

위 예제에서는 두 개의 람다 식이 사용되었습니다.

  • 단항 연산(xx * xx): 입력 벡터의 각 요소를 제곱합니다.
  • 이진 연산(xx + yy): 변환된 현재 값과 바로 앞 요소까지의 누적 값을 더합니다.

입력 벡터 {11, 22, 33, 44, 55, 66, 77, 88}의 각 요소를 제곱하면 {121, 484, 1089, 1936, 3025, 4356, 5929, 7744}가 되고, 이를 차례대로 누적하면 다음과 같은 결과가 만들어집니다.

  • 첫 번째 요소: 121
  • 두 번째 요소: 121 + 484 = 605
  • 세 번째 요소: 605 + 1089 = 1694
  • 네 번째 요소: 1694 + 1936 = 3630
  • 이후 요소들도 동일한 방식으로 계속 누적됩니다.

이처럼 transform_inclusive_scan()은 데이터 변환과 누적 계산을 한 번의 순회로 동시에 처리할 수 있어, 부분합 계산이나 통계 데이터 처리 등에서 매우 유용하게 활용됩니다.