Pregunta

Necesito almacenar una colección de enteros y dobles (que representa el valor nominal y real de los valores de datos en c++.Yo obviamente podría almacenar todo en un std::vector<double> pero esto se siente un poco mal y no se obtiene la estética puntos de bonificación.

Yo también podría cocinar algo basado en el polimorfismo, pero también tengo la colección para ser realmente eficiente:ambos almacenar y recuperar los datos de la colección debe ser tan rápido como sea posible.Me resulta difícil juzgar si tal solución sería máximamente eficaz.

También encontré boost::variante, que puede ser de ayuda aquí.

Información adicional:el número de elementos en la colección será pequeño (<100) y conocida en el momento de la inicialización de la colección.

Resumiendo:Yo obviamente podría resolver esto en un sinnúmero de maneras, pero no estoy seguro de lo que podría ser una buena solución cuando (i) la eficiencia es muy importante y (ii) también quiero escribir algo bonito de código.¿Cuál es mi mejor apuesta aquí?

Editar información adicional: La colección representa una 'fila' en un mayor conjunto de datos, sus elementos representan los valores de ciertas 'columnas'.Las propiedades de las filas se conoce, por lo que se sabe qué tipo de datos se almacena en la posición.La "eficiencia" de que estoy hablando, es principalmente la eficiencia de la recuperación de la int/doble valor de una determinada columna, aunque el rápido ajuste de los valores es importante también.Tengo algunas funciones que operan sobre los datos que necesita para recuperar tan rápido como sea posible.Ejemplo:

typedef std::vector<double> Row;

void doubleFun(Row const &row)
{
    // Function knows there's always a double at index 0
    double value = row[0];
    ...
}

void integerFun(Row const &row)
{
    // Function knows there's always an integer at index 1
    int value = row[1];
    ...
}

Después de un poco más de pensamiento y lectura de las sugerencias hasta el momento, parece que sólo almacenar int columnas y columnas dobles en dos vectores es una solución sólida.La colección Row podría entonces sólo definir dos miembros diferentes para recuperar el valor nominal y real de los datos que las funciones que se pueden utilizar.

Almacenar como un vector<double> está bien también, supongo, pero depende de la rapidez de la conversión entre el doble y el int es (que es probablemente bastante impresionante).

Lo siento por ser un poco confuso al principio, espero que sea más clara y ahora, y que puedo conseguir algo más de idea sobre el tema.

¿Fue útil?

Solución

¿Pedir un punto importante en su contenedor?

Si no es así:

class MyContainer
{
    std::vector<double> doubles;
    std::vector<int>    ints;

    push(double value) { doubles.push_back(value); }
    push(int value)    { ints.push_back(value); }

   ....
};

La parte del iterador (para explorar todo el contenedor) podría ser un poco más complicado ...

Otros consejos

¿Por qué no usar directamente un vector de doble? Dado que los enteros se pueden convertir en dobles sin pérdida de precisión ... me parece la solución más simple y eficiente.

Lo que queda por configurar (y no pude entender en su pregunta) cómo puede marcar la diferencia entre los valores normales y reales. El problema permanece abierto en cualquier solución que pueda elegir.

Usted podría utilizar un tipo de unión y el uso que en su vector.Pero en ese caso tendrías que haber alguna forma de saber que los elementos del vector debe ser tratada como enteros y cuáles deben ser tratados como dobles.Para mantener un seguimiento de cuáles son enteros y cuáles son dobles puede utilizar un bitset o algo por el estilo.

No estoy seguro de si su objetivo es evitar pesados cálculos de punto flotante.Si es entonces el bitset puede ser más eficiente.Si no, y exacta int precisión no es importante, entonces usted podría almacenar todos ellos como dobles.

#include <vector>
#include <bitset>

union di
{
    double d;
    int i;
};


int main(int argc, char* argv[])
{

    std::bitset<2> bitsetInts;

    std::vector<di> v;
    di e1;
    e1.d = 3.9;
    v.push_back(e1);

    di e2;
    e2.i = 3;
    bitsetInts.set(1);
    v.push_back(e2);

    return 0;
}

Yo iría por el boost::variant Solución, se ajusta perfectamente a sus necesidades.

Existe la tupla Boost, que puede usar si conoce los tipos en el momento de la compilación. Pero si el número de artículos es pequeño, eficientemente en desperdicio de 100 bytes no debería ser una preocupación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top