Question

Je dois stocker une collection de ints et doubles (représentant des données nominales et valeurs réelles) en c ++. Je ne pouvais évidemment les stocker dans un std::vector<double>, mais cela se sent un peu mal et ne soit pas l'esthétique des points bonus.

Je pourrais aussi faire cuire quelque chose basé sur le polymorphisme, mais je dois aussi la collection pour être vraiment efficace: à la fois le stockage et la récupération des données de la collection devrait être aussi rapide que possible. Je trouve qu'il est difficile de juger si une telle solution serait plus efficace possible.

J'ai aussi trouvé boost :: variante , ce qui pourrait être utile ici.

Informations complémentaires:. Le nombre d'éléments de la collection sera faible (<100) et connu lors de l'initialisation de la collection

Résumer: Je pourrais évidemment résoudre ce de multiples façons, mais je ne suis pas sûr ce serait une bonne efficacité solution lorsque (i) est vraiment important et (ii) Je veux aussi écrire un code assez agréable. Ce qui est ici mon meilleur pari?

Modifier, Informations complémentaires: La collection représente une « rangée » dans un ensemble de données plus large, ses éléments représentent les valeurs de certains « colonnes ». Les propriétés des lignes sont connues, il est donc connu ce genre de données sont stockées à quelle position. Le Je parle « efficacité » au sujet est avant tout l'efficacité de la récupération de l'int / valeur double d'une certaine colonne, bien que prise rapide des valeurs est trop importante. J'ai quelques fonctions qui fonctionnent sur les données qui ont besoin de récupérer aussi vite que possible. Exemple:

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];
    ...
}

Après un peu plus la pensée et la lecture des suggestions, il semble si loin que juste le stockage des colonnes int et doubles colonnes dans deux vecteurs séparés est une solution solide. Le Row de collection pourrait alors définir seulement deux membres différents pour récupérer des données nominales et réelles que les fonctions peuvent utiliser.

Il suffit de stocker en tant que vector<double> est bien aussi, je suppose, mais cela dépend de la rapidité de la conversion entre le double et int est (ce qui est probablement assez impressionnant).

Désolé d'être un peu clair au début, j'espère que ce sera plus clair et maintenant et que je peux obtenir quelques réflexions plus sur la question.

Était-ce utile?

La solution

est la commande d'un point important dans votre réservoir?

Dans le cas contraire:

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 partie iterator (pour parcourir l'ensemble conteneur) pourrait être un peu plus délicat ...

Autres conseils

Pourquoi ne pas utiliser directement un vecteur double? Puisque les nombres entiers peuvent être convertis en double sans perte de précision ... il me semble la solution la plus simple et la plus efficace.

Ce qui reste à définir (et je ne pouvais pas comprendre de votre question) comment pouvez-vous faire la différence entre les valeurs normales et réelles. La question reste ouverte dans une solution que vous pouvez choisir.

Vous pouvez utiliser un type d'union et l'utiliser dans votre vecteur. Mais dans ce cas, vous auriez à avoir un moyen de savoir quels éléments du vecteur doivent être traités comme ints et ceux qui doivent être traités comme doubles. Pour garder une trace de ceux qui sont ints et ceux qui sont doubles, vous pouvez utiliser un bitset ou quelque chose comme ça.

Je ne sais pas si votre objectif est d'éviter de lourdes calculs en virgule flottante. Si elle est alors le bitset peut être plus efficace. Dans le cas contraire, et la précision int exacte est pas important, alors vous pourriez tout aussi bien les stocker en double.

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

Je pencherais pour la solution boost::variant, il convient parfaitement à vos besoins.

Il y a tuple boost, que vous pouvez utiliser si vous connaissez les types au moment de la compilation. Mais si le nombre d'éléments est petit, efficace de perdre 100 octets ne devrait pas être une préoccupation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top