반응형
accumulate 사용법과 주의사항
INTRO
C++ 에서 알고리즘을 공부하다가 accumulate 함수를 발견했습니다.
생각보다 편리한 기능이고 사용하기도 편했어요.
간편하게 배열의 합을 구할 수 있습니다.
2. 헤더 정보
#include <numeric> 를 include 하시면 됩니다.
3. 기본 사용법
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = std::accumulate(v.begin(), v.end(), 0);
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
auto dash_fold = [](std::string a, int b) {
return std::move(a) + '-' + std::to_string(b);
};
std::string s = std::accumulate(std::next(v.begin()), v.end(),
std::to_string(v[0]), // start with first element
dash_fold);
// Right fold using reverse iterators
std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
std::to_string(v.back()), // start with last element
dash_fold);
std::cout << "sum: " << sum << '\n'
<< "product: " << product << '\n'
<< "dash-separated string: " << s << '\n'
<< "dash-separated string (right-folded): " << rs << '\n';
}
sum: 55
product: 3628800
dash-separated string: 1-2-3-4-5-6-7-8-9-10
dash-separated string (right-folded): 10-9-8-7-6-5-4-3-2-1
참고사이트에서 가져온 예제입니다.
예시와 결과값을 보면 와닿을 것입니다.
첫번째와 두번째는 first, last iterator이 들어가고 세번째 인자는 initial value of the sum 값이 들어갑니다.
4. 주의 사항
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
void main()
{
vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
cout << accumulate(v.begin(), v.end(), 0) << endl;
vector<long long> v2{ 1'000'000'000, 2'000'000'000, 3'000'000'000, 4'000'000'000 };
cout << accumulate(v2.begin(), v2.end(), 0) << endl;
cout << accumulate(v2.begin(), v2.end(), 0LL) << endl;
return;
}
55
1410065408
10000000000
여기서 세 번째 인자 '합의 초기값(initial value of the sum)'이 어떤 역할을 하는지 알 수 있습니다.
첫번째 예시의 경우는 int형으로 범위를 초과하지 않아 제대로 출력되고 있습니다.
그러나, 두번째 예시의 경우! 쓰레기값이 출력됩니다.
세번째 예시의 경우는 초기값을 잘 설정했을 경우, 제대로 나오는 것을 볼 수 있습니다.
즉, 범위를 초과하는 값들을 더할때는 초기값을 잘 설정해주어야하고,
이러한 문제가 발생한 이유는 accumlate의 반환값이 initial value의 타입을 따라 가기 때문입니다.
어떠한 경고도 뜨지 않고 자동으로 캐스팅되기때문에 주의할 필요가 있습니다.
template<class InputIt, class T>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first) {
init = std::move(init) + *first; // std::move since C++20
}
return init;
}
참고 사이트에서 가져온 함수 원형 첫번째 버전입니다.
여기를 보면 템플릿으로 반환값이 init과 동일한 것을 볼 수 있습니다.
5. 참고 사이트
반응형
'C, C++' 카테고리의 다른 글
[C/C++]explicit (0) | 2021.12.01 |
---|---|
[C/C++]스마트 포인터(smart pointer) (0) | 2021.11.22 |
[C/C++] stringstream 사용법 (0) | 2021.07.03 |
[C/C++]enum과 enum class (0) | 2021.04.05 |
[C/C++] 다형성 - 가상 함수 (0) | 2020.09.10 |