에서 모든 요소의 합을 찾는 좋은 방법은 무엇입니까 std::vector
?
std::vector<int> vector
요소가 몇 개 있는 벡터가 있다고 가정 합니다. 이제 모든 요소의 합계를 찾고 싶습니다. 동일한 방법은 무엇입니까?
답변
실제로는 몇 가지 방법이 있습니다.
int sum_of_elems = 0;
C ++ 03
-
클래식 for 루프 :
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it) sum_of_elems += *it;
-
표준 알고리즘 사용 :
#include <numeric> sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
중요 참고 : 마지막 인수의 유형은 초기 값 뿐만 아니라 결과 유형 에도 사용됩니다. 거기에 int를 넣으면 벡터가 플로팅 되어도 int가 누적됩니다. 당신은 부동 소수점 숫자, 변경 합산하는 경우
0
에0.0
또는0.0f
(nneonneo 덕분에). 아래의 C ++ 11 솔루션도 참조하십시오.
C ++ 11 이상
-
비. 향후 변경시에도 벡터 유형을 자동으로 추적합니다.
#include <numeric> sum_of_elems = std::accumulate(vector.begin(), vector.end(), decltype(vector)::value_type(0));
-
사용
std::for_each
:std::for_each(vector.begin(), vector.end(), [&] (int n) { sum_of_elems += n; });
-
범위 기반 for 루프 사용 (Roger Pate 덕분에) :
for (auto& n : vector) sum_of_elems += n;
답변
가장 쉬운 방법은 다음을 사용 std:accumuate
하는 것입니다 vector<int> A
.
#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
답변
Prasoon은 이미이 작업을 수행하기위한 여러 가지 (좋은) 방법을 제공했지만 여기서는 반복 할 필요가 없습니다. 그러나 속도에 대한 대체 접근법을 제안하고 싶습니다.
이 작업을 꽤 많이 수행하려는 경우 벡터의 “하위 분류”를 고려하여 요소의 합계가 별도로 유지되도록 할 수 있습니다 ( 실제로 하위 분류 벡터가 아님 ). 가상 소멸자 – 나는, 그 안에 합 벡터를 포함하는 클래스의 더 이야기하고 has-a
대신를 is-a
) 및 벡터와 같은 방법을 제공합니다.
빈 벡터의 경우 합계는 0으로 설정됩니다. 벡터에 삽입 할 때마다 합계에 삽입되는 요소를 추가하십시오. 삭제할 때마다 빼십시오. 기본적으로 합계를 일관되게 유지하기 위해 기본 벡터를 변경할 수있는 모든 항목 을 가로 챕니다.
이렇게하면 어느 시점에서든 합계를 “계산”할 수있는 매우 효율적인 O (1) 방법이 있습니다 (현재 계산 된 합계 만 반환). 총계를 조정할 때 삽입 및 삭제가 약간 더 오래 걸리므로이 성능 저하를 고려해야합니다.
합계를 계산하는 비용이 모든 액세스에 대해 상각되기 때문에 벡터가 변경되는 것보다 더 자주 합계가 필요한 벡터가이 체계의 이점을 얻을 수 있습니다. 분명히, 매 시간 합계 만 필요하고 벡터가 초당 3 천 번 변경되면 적합하지 않습니다.
이와 같은 것으로 충분합니다.
class UberVector:
private Vector<int> vec
private int sum
public UberVector():
vec = new Vector<int>()
sum = 0
public getSum():
return sum
public add (int val):
rc = vec.add (val)
if rc == OK:
sum = sum + val
return rc
public delindex (int idx):
val = 0
if idx >= 0 and idx < vec.size:
val = vec[idx]
rc = vec.delindex (idx)
if rc == OK:
sum = sum - val
return rc
분명히, 그것은 의사 코드이며 약간 더 많은 기능을 원할 수도 있지만 기본 개념을 보여줍니다.
답변
합산을 뒤로 할 수 있는데 왜 합산을 수행 합니까? 주어진:
std::vector<int> v; // vector to be summed
int sum_of_elements(0); // result of the summation
우리는 첨자를 사용할 수 있습니다.
for (int i(v.size()); i > 0; --i)
sum_of_elements += v[i-1];
범위 검사 된 “첨자”를 사용할 수 있습니다.
for (int i(v.size()); i > 0; --i)
sum_of_elements += v.at(i-1);
for 루프에서 역 반복자를 사용할 수 있습니다.
for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
sum_of_elements += *i;
for 루프에서 앞뒤로 반복하는 순방향 반복자를 사용할 수 있습니다 (oooh, 까다로운!) :
for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
sum_of_elements += *(i - 1);
우리는 accumulate
역 반복자와 함께 사용할 수 있습니다 :
sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
for_each
역 반복자를 사용하여 람다 식과 함께 사용할 수 있습니다 .
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
보시다시피, 벡터 순방향을 합산하는 것만 큼 벡터를 역방향으로 합산하는 방법은 여러 가지가 있으며, 이들 중 일부는 훨씬 더 흥미롭고 일대일 오류에 대한 훨씬 더 큰 기회를 제공합니다.
답변
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
답변
하나는 사용할 수있는 std::valarray<T>
다음과 같은
#include<iostream>
#include<vector>
#include<valarray>
int main()
{
std::vector<int> seq{ 1,2,3,4,5,6,7,8,9,10 };
std::valarray<int> seq_add{ seq.data(), seq.size() };
std::cout << "sum = " << seq_add.sum() << "\n";
return 0;
}
벡터valarray
의 크기만큼 크기가 커야 하고 초기화하는 데 시간이 걸리기 때문에 일부는이 방법을 효율적으로 찾지 못할 수 있습니다 .valarray
이 경우에는 사용하지 말고 시퀀스를 요약하는 또 다른 방법으로 사용하십시오.
답변
C ++ 0x 만 해당 :
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
이는 다른 곳에서 언급 된 BOOST_FOREACH와 유사하며, 누적 또는 for_each와 함께 사용되는 상태 저장 펑터와 비교하여 더 복잡한 상황에서도 명확성의 이점이 있습니다.