c++ - resultado - separar valores negativos y positivos en excel
El vector convirtió todos los valores negativos a cero (5)
Cuando declaraste el vector con
std::vector<int> v(5);
Ha creado v
almacenar cinco espacios de 4 bytes en la memoria (suponiendo un int = 4 bytes en su sistema), y de forma predeterminada todos estos espacios de 4 bytes almacenan los bits que representan los 0. Luego, empujaste 5 ints más (-1, -2, -3, -4, -5) al final del vector con:
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
En este punto, el vector tiene 10 elementos, los primeros cinco son los enteros desconocidos que almacenan 0 en la instancia en la que ejecutó el programa. Como su bucle for imprime los primeros cinco elementos en el vector, esta es la razón por la cual imprimió todos los 0.
Hice un vector de tamaño constante para almacenar valores negativos, y luego imprimiendo los valores todo lo que obtuve fueron ceros. Solo quiero saber por qué no está almacenando valores negativos.
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(5);
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
for (int i=0; i<5; i++)
std::cout << v[i] << " "; // All I got was zeroes
}
El constructor que invoca completa los primeros 5 elementos con ceros, vea aquí (# 3 en la lista de sobrecargas):
Construye el contenedor con el recuento de instancias de T predeterminadas
(donde la "instancia insertada por defecto" de un int
es 0). Lo que podrías haber querido es
std::vector<int> v;
v.reserve(5); /* Prevent unnecessary allocations as you know the desired size. */
v.push_back(-1);
/* ... */
Una alternativa que utiliza la llamada de constructor original es
#include <numeric>
std::vector<int> v(5);
std::iota(v.rbegin(), v.rend(), -v.size());
aunque esto hace más trabajo de lo necesario ya que cada elemento primero se construye por defecto y luego se le asigna un nuevo valor nuevamente.
Eso es porque push_back
pone nuevos elementos en el extremo del vector.
Puede ver el efecto ejecutando i
a 9
: los números negativos ocuparán v[5]
a v[9]
.
Escritura
std::vector<int> v{-1, -2, -3, -4, -5};
en cambio es una solución particularmente elegante.
Este es un caso donde el principio DRY te ayudaría a entender tu error.
vector<int> v(5);
...
for(int i=0;i<5;i++)
Aquí está creando una matriz, para la cual cree que reserva espacio para 5 elementos. Luego insertas esos 5 elementos. Después de eso, quería imprimir los contenidos de toda la matriz, pero en lugar de simplemente escribir v.size()
, repitió el 5
, por lo que su código ahora se lee como "Imprimir los primeros cinco elementos de v
", en lugar de "Imprimir todos los elementos" de v
".
Si en cambio escribes lo que quieres decir, verás que la matriz en realidad tiene 10 elementos, no 5.
Por cierto, desde C ++ 11 puedes recorrer todos los elementos de una manera más directa:
for(int x : v)
o, si los elementos son un poco más costosos, puede usar referencias a los elementos, incluso referencias de tipo auto
:
for(auto& x : v)
Esta nueva sintaxis de bucle se denomina bucle for
-based .
Puede considerar el vector
una versión flexible de la matriz primitiva en C / C ++. Cuando inicializa un vector
con un tamaño n
, el vector
construido tiene un tamaño de n
(o tal vez más grande en la memoria, pero no lo sabe, ya que el compilador lo maneja implícitamente). Tenga en cuenta que aquí n
representa el número de entradas, pero no el uso real de la memoria (es decir, bytes). Si no lo inicializa con un parámetro de tamaño, el vector
está vacío con el tamaño 0, pero en la memoria tendría un tamaño de memoria predeterminado implícito.
Digamos que su vector
actual tiene el tamaño 5. Y desea push_back()
en otro elemento, entonces el vector
internamente reasignará la matriz completa a una nueva ubicación de memoria que podría contener todas sus entradas antiguas más la nueva. De modo que no necesita reasignar la memoria manualmente, como lo que tiene que hacer en C.
Aquí, en su ejemplo, para completar esos 5 enteros negativos en su vector
, hay un par de formas.
1) Puede inicializar un vector
sin especificar el tamaño. Y luego presione cada elemento que desee.
vector<int> v;
for (int i = -1; i >= -5; --i) {
v.push_back(i);
}
2) Puedes inicializar el vector
en tu camino con ese parámetro de tamaño. Y luego asigneles nuevos valores.
vector<int> v(5);
for (int i = 0; i < v.size(); ++i) {
v[i] = -i;
}
3) También puede inicializar el vector
con esas entradas cuando se construye.
vector<int> v{-1, -2, -3, -4, -5};
or vector<int> v = {-1, -2, -3, -4, -5};