Jak podsumować elementy wektora C++?

Jakie sąDobre sposoby znajdowania sumy wszystkich pierwiastków w std::vector?

Załóżmy, że mam wektor std::vector<int> vector z kilkoma elementami w nim. Teraz chcę znaleźć sumę wszystkich elementów. Jakie są różne sposoby na to samo?

 180
Author: noɥʇʎԀʎzɐɹƆ, 2010-07-11

8 answers

Właściwie jest kilka metod.

int sum_of_elems = 0;

C++03

  1. Klasyczna dla pętli:

    for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
        sum_of_elems += *it;
    
  2. Używając standardowego algorytmu:

    #include <numeric>
    
    sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
    

    Flaga

    bądź ostrożny z akumulować. typ ostatniego argumentu jest używany nie tylko dla wartości początkowej, ale także dla typu wyniku. Jeśli umieścisz tam int, będzie on gromadził ints nawet jeśli wektor ma float. Jeśli sumujesz liczby zmiennoprzecinkowe, Zmień 0 do 0.0 lub 0.0f (dzięki nneonneo).

C++11 i wyżej

  1. Używając std::for_each:

    std::for_each(vector.begin(), vector.end(), [&] (int n) {
        sum_of_elems += n;
    });
    
  2. Użycie pętli for opartej na przedziałach (dzięki Rogerowi Pate ' owi):

    for (auto& n : vector)
        sum_of_elems += n;
    
 343
Author: Prasoon Saurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-30 12:56:02

Prasoon zaoferował już wiele różnych (i dobrych) sposobów, aby to zrobić, z których żaden nie musi się tutaj powtarzać. Chciałbym jednak zaproponować alternatywne podejście do prędkości.

Jeśli zamierzasz robić to dość często, możesz rozważyć "podkategorię" swojego wektora tak, aby suma elementów była utrzymywana osobno (Nie w rzeczywistości podkategorii wektor, który jest niepewny z powodu braku Wirtualnego destruktora-mówię bardziej o klasie, która zawiera sumę i Wektor. wektor wewnątrz niego, has-a zamiast is-a i dostarcza metody wektorowe).

Dla wektora pustego suma jest ustawiona na zero. Przy każdym wstawieniu do wektora Dodaj element wstawiany do sumy. Przy każdym usunięciu odejmuj. Zasadniczo, Wszystko , które może zmienić wektor bazowy, jest przechwytywane, aby zapewnić spójność sumy.

W ten sposób masz bardzo efektywną metodę O(1) do "obliczania" sumy w dowolnym momencie (po prostu zwróć sumę obecnie obliczane). Wstawianie i usuwanie potrwa nieco dłużej, ponieważ dostosujesz sumę i powinieneś wziąć to uderzenie wydajności pod uwagę.

Wektory, w których suma jest potrzebna częściej niż wektor jest zmieniany, są tymi, które mogą skorzystać z tego schematu, ponieważ koszt obliczenia sumy jest amortyzowany we wszystkich dostępach. Oczywiście, jeśli potrzebujesz tylko sumy co godzinę, a wektor zmienia się trzy tysiące razy na sekundę, to nie będzie odpowiednie.

Coś takiego by wystarczyło:

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

Oczywiście, to pseudo-kod i możesz chcieć mieć trochę więcej funkcjonalności, ale pokazuje podstawową koncepcję.

 31
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-12 00:24:38

Po co wykonywać podsumowanie do przodu, skoro można to zrobić do tyłu ?

std::vector<int> v;     // vector to be summed
int sum_of_elements(0); // result of the summation

Możemy użyć zapisu, licząc wstecz:

for (int i(v.size()); i > 0; --i)
    sum_of_elements += v[i-1];

Możemy użyć sprawdzonego zakresu "subscripting", licząc wstecz (na wszelki wypadek):

for (int i(v.size()); i > 0; --i)
    sum_of_elements += v.at(i-1);

Możemy używać iteratorów odwrotnych w pętli for:

for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
    sum_of_elements += *i;

Możemy używać iteratorów do przodu, iteracji do tyłu, w pętli for (Oooh, tricky!):

for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
    sum_of_elements += *(i - 1);

Możemy używać accumulate z iteratorami odwrotnymi:

sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);

We może używać for_each z wyrażeniem lambda za pomocą iteratorów odwrotnych:

std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });

Tak więc, jak widzisz, istnieje tak samo wiele sposobów sumowania wektora do tyłu, jak sumowania wektora do przodu, a niektóre z nich są o wiele bardziej ekscytujące i oferują znacznie większe możliwości błędów off-by-one.

 21
Author: James McNellis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 12:06:31
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
 13
Author: rafak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-06 15:40:40

C++0x only:

vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;

Jest to podobne do boost_foreach wymienionych gdzie indziej i ma tę samą zaletę jasności w bardziej złożonych sytuacjach, w porównaniu do funkcjonorów stateful używanych z accumulate lub for_each.

 5
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-11 20:16:52

Jestem użytkownikiem Perla, gra, którą mamy, polega na znalezieniu różnych sposobów na zwiększenie zmiennej... tu nie jest inaczej. Odpowiedź na ile sposobów można znaleźć sumę elementów wektora w C++ to prawdopodobnie an infinity...

Moje 2 grosze:

Użycie BOOST_FOREACH, aby uwolnić się od brzydkiej składni iteratora:

sum = 0;
BOOST_FOREACH(int & x, myvector){
  sum += x;
}

Iteracja indeksów (naprawdę łatwa do odczytania).

int i, sum = 0;
for (i=0; i<myvector.size(); i++){
  sum += myvector[i];
}

Ten drugi jest destrukcyjny, dostęp do wektora jak stos:

while (!myvector.empty()){
   sum+=myvector.back();
   myvector.pop_back();
}
 5
Author: kriss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-20 13:29:17

Można również użyć STD:: valarray w ten sposób

#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;
}

Niektórzy mogą nie uznać tego za skuteczny, ponieważ rozmiar valarray musi być tak duży, jak rozmiar wektora, a inicjalizacja valarray również zajmie trochę czasu.

W takim przypadku nie używaj go i weź go jako kolejny sposób podsumowania sekwencji.

Thanks

 1
Author: NeutronStar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 09:30:18

Znalazłem najprostszy sposób, aby znaleźć sumę wszystkich elementów vector

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

int main()
{
    vector<int>v(10,1);
    int sum=0;
    for(int i=0;i<v.size();i++)
    {
        sum+=v[i];
    }
    cout<<sum<<endl;

}

W tym programie Mam wektor wielkości 10 i są inicjalizowane przez 1. Obliczyłem sumę za pomocą prostej pętli jak w tablicy.

 0
Author: Ravi Kumar Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 11:07:31