Frage

Ich muss eine Sammlung von INTs und Doppel (die nominalen und realen Daten darstellen) in C ++ speichern. Ich konnte sie offensichtlich alle in einem aufbewahren std::vector<double> , aber das fühlt sich ein bisschen falsch an und bekommt die Ästhetik -Bonuspunkte nicht.

Ich könnte auch etwas auf der Grundlage von Polymorphismus kochen, aber ich brauche auch die Sammlung, um wirklich effizient zu sein: Das Speichern und Abrufen der Daten in der Sammlung sollte so schnell wie möglich sein. Es fällt mir schwer zu beurteilen, ob eine solche Lösung maximal effizient wäre.

Ich habe auch gefunden Boost :: Variante, was hier hilfreich sein könnte.

Zusätzliche Informationen: Die Anzahl der Elemente in der Sammlung ist klein (<100) und bei der Initialisierung der Sammlung bekannt.

Zusammenfassen: Ich könnte dies offensichtlich auf unzählige Weise lösen, aber ich bin mir nicht sicher, was eine gute Lösung wäre, wenn (i) Effizienz wirklich wichtig ist und (ii) ich auch einen etwas schönen Code schreiben möchte. Was ist meine beste Wette hier?

Bearbeiten, zusätzliche Informationen: Die Sammlung stellt eine "Zeile" in einem größeren Datensatz dar, ihre Elemente repräsentieren die Werte bestimmter "Spalten". Die Eigenschaften der Zeilen sind bekannt, daher ist bekannt, welche Art von Daten an welcher Position gespeichert sind. Die "Effizienz", über die ich spreche, ist in erster Linie die Effizienz des Abrufens des int/doppelten Werts einer bestimmten Spalte, obwohl auch die schnelle Einstellung der Werte auch wichtig ist. Ich habe einige Funktionen, die mit den Daten arbeiten, die sie so schnell wie möglich abrufen müssen. Beispiel:

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

Nach einigen weiteren Gedanken und Lesen der Vorschläge bisher scheint es eine feste Lösung zu sein, int -Spalten und Doppelspalten in zwei separaten Vektoren zu speichern. Die Sammlung Row Könnte dann nur zwei verschiedene Mitglieder zum Abrufen nominaler und realer Daten definieren, die die Funktionen verwenden können.

Einfach als als speichern vector<double> Ist auch in Ordnung, denke ich, aber es hängt davon ab, wie schnell die Konvertierung zwischen Double und INT ist (was wahrscheinlich ziemlich beeindruckend ist).

Es tut mir leid, dass ich zunächst ein wenig unklar bin. Ich hoffe, es ist klarer und jetzt kann ich noch ein paar Gedanken darüber bekommen.

War es hilfreich?

Lösung

Ist es ein wichtiger Punkt in Ihrem Container?

Wenn nicht:

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

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

   ....
};

Der Iterator -Teil (um den gesamten Behälter zu durchsuchen) könnte etwas schwieriger sein ...

Andere Tipps

Warum nicht direkt einen Doppelvektor verwenden? Da Ganzzahlen ohne Präzisionsverlust in Doppel konvertiert werden können, sieht es mir die einfachste und effizienteste Lösung aus.

Was bleibt zu setzen (und ich konnte nicht aus Ihrer Frage herausfinden), wie können Sie den Unterschied zwischen normalen und realen Werten machen? Das Problem bleibt in jeder Lösung offen, die Sie wählen könnten.

Sie können einen Gewerkschaftstyp verwenden und dies in Ihrem Vektor verwenden. In diesem Fall müssten Sie jedoch eine Möglichkeit haben, zu wissen, welche Elemente des Vektors als INTs behandelt werden sollten und welche als Doppel behandelt werden sollten. Um den Überblick zu behalten, welche in INTs sind und welche Doppel Sie haben, können Sie einen Bitset oder ähnliches verwenden.

Ich bin mir nicht sicher, ob Ihr Ziel es ist, starke Berechnungen für schwimmende Punkte zu vermeiden. Wenn dies der Fall ist, kann der Bitset effizienter sein. Wenn nicht, und genaue int -Präzision ist nicht wichtig, können Sie sie genauso gut als Doppel speichern.

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

Ich würde mich für die entscheiden boost::variant Lösung, es passt perfekt zu Ihren Bedürfnissen.

Es gibt das Boost -Tupel, das Sie verwenden können, wenn Sie die Typen zur Kompilierungszeit kennen. Aber wenn die Anzahl der Artikel gering ist, sollte es kein Problem sein, 100 Bytes zu verschwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top