una - sumar elementos de un vector c++
¿Cómo resumir los elementos de un vector C++? (7)
¿Cuáles son las buenas formas de encontrar la suma de todos los elementos en un std::vector
?
Supongamos que tengo un vector std::vector<int> vector
con algunos elementos en él. Ahora quiero encontrar la suma de todos los elementos. ¿Cuáles son las diferentes formas de hacer lo mismo?
¿Por qué realizar la sumatoria cuando puedes hacerlo al revés ? Dado:
std::vector<int> v; // vector to be summed
int sum_of_elements(0); // result of the summation
Podemos usar la suscripción, contando hacia atrás:
for (int i(v.size()); i > 0; --i)
sum_of_elements += v[i-1];
Podemos usar "subscripting" de rango controlado, contando hacia atrás (por si acaso):
for (int i(v.size()); i > 0; --i)
sum_of_elements += v.at(i-1);
Podemos usar iteradores inversos en un ciclo for:
for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
sum_of_elements += *i;
Podemos usar iteradores directos, iterando hacia atrás, en un ciclo for (oooh, ¡complicado!):
for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
sum_of_elements += *(i - 1);
Podemos usar accumulate
con iteradores inversos:
sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
Podemos usar for_each
con una expresión lambda utilizando iteradores inversos:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
Entonces, como puede ver, hay tantas formas de sumar el vector hacia atrás como de sumar el vector hacia adelante, y algunas de ellas son mucho más emocionantes y ofrecen una oportunidad mucho mayor para los errores uno a uno.
C ++ 0x solamente:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
Esto es similar al BOOST_FOREACH mencionado en otro lugar y tiene el mismo beneficio de claridad en situaciones más complejas, en comparación con los funtores con estado que se usan con accumulate o for_each.
En realidad, hay bastantes métodos.
int sum_of_elems = 0;
C ++ 03
Clásico para bucle:
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it) sum_of_elems += *it;
Usando un algoritmo estándar:
#include <numeric> sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
bandera
Tenga cuidado con acumular. El tipo del último argumento se utiliza no solo para el valor inicial, sino también para el tipo del resultado. Si coloca un int allí, acumulará enter incluso si el vector tiene float. Si está sumando números de punto flotante, cambie
0
a0.0
o0.0f
(gracias a nneonneo).
C ++ 11 y superior
Usando
std::for_each
:std::for_each(vector.begin(), vector.end(), [&] (int n) { sum_of_elems += n; });
Usando un bucle for basado en rango (gracias a Roger Pate):
for (auto& n : vector) sum_of_elems += n;
Prasoon ya ha ofrecido una gran cantidad de formas diferentes (y buenas) de hacerlo, ninguna de las cuales es necesario repetir aquí. Sin embargo, me gustaría sugerir un enfoque alternativo para la velocidad.
Si va a hacer esto un poco, puede considerar "subclasificar" su vector para que la suma de los elementos se mantenga por separado (no subclasificar el vector, lo que es dudoso debido a la falta de un vector). destructor virtual: estoy hablando más de una clase que contiene la suma y un vector dentro de ella, has-a
lugar de is-a
, y proporciona los métodos tipo vector).
Para un vector vacío, la suma se establece en cero. En cada inserción del vector, agregue el elemento que se inserta a la suma. En cada eliminación, restarlo. Básicamente, todo lo que puede cambiar el vector subyacente se intercepta para garantizar que la suma se mantenga constante.
De esta forma, tiene un método O (1) muy eficiente para "calcular" la suma en cualquier punto en el tiempo (simplemente devuelva la suma calculada actualmente). La inserción y eliminación demorará un poco más a medida que ajuste el total y debe tener en cuenta este rendimiento.
Los vectores donde la suma se necesita con más frecuencia que el vector se cambian son los que probablemente se beneficien de este esquema, ya que el costo de calcular la suma se amortiza en todos los accesos. Obviamente, si solo necesitas la suma cada hora y el vector está cambiando tres mil veces por segundo, no será adecuado.
Algo como esto sería suficiente:
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
Obviamente, eso es un pseudocódigo y es posible que desee tener un poco más de funcionalidad, pero muestra el concepto básico.
Soy un usuario de Perl, un juego que tenemos es encontrar diferentes maneras de incrementar una variable ... eso no es realmente diferente aquí. La respuesta a cuántas formas de encontrar la suma de los elementos de un vector en C ++ es probablemente an infinity
...
Mis 2 centavos:
Usando BOOST_FOREACH, para liberarse de la sintaxis del iterador feo:
sum = 0;
BOOST_FOREACH(int & x, myvector){
sum += x;
}
iterando en índices (realmente fácil de leer).
int i, sum = 0;
for (i=0; i<myvector.size(); i++){
sum += myvector[i];
}
Este otro es destructivo, accediendo al vector como una pila:
while (!myvector.empty()){
sum+=myvector.back();
myvector.pop_back();
}
También se puede usar std :: valarray como este
#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;
}
Puede que algunos no lo encuentren así de eficiente ya que el tamaño de valarray debe ser tan grande como el tamaño del vector y la inicialización de valarray también llevará tiempo.
En ese caso, no lo use y tómelo como una forma más de resumir la secuencia.
Gracias
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);