Domanda

Ho progettato una biblioteca aritmetica vettoriale rapido e di base in C ++. Chiamo il programma dalla riga di comando quando ho bisogno di un prodotto trasversale rapido, o angolo tra vettori. Non faccio uso di Matlab o Octave o correlate, in quanto il tempo di avvio è più grande del tempo di calcolo. Ancora una volta, questo è per le operazioni di base.

sto estendendo questo programma, e io farlo funzionare come un calcolatore RPN, per le operazioni del tipo:

1 2 3
4 5 6
x
out: -3 6 -3

(indicare un vettore, un altro vettore, e l'operatore "croce", sputare il prodotto vettoriale)

La pila deve accettare vettori o scalari 3D, per le operazioni come:

1 2 3
2
*
out: 2 4 6

Il lexer e parser per questo mini-calcolatrice sono banali, ma io non riesco a pensare ad un buon modo per creare la pila interna. Come si creerebbe una pila di per contenere vettori o doppie (mi sono rimboccato la mia classe molto semplice vettore - meno di cento righe e fa tutto quello che ho bisogno).

Come posso creare un semplice pila che accetta elementi della classe Vector o di tipo double?

Grazie.

È stato utile?

Soluzione

Il modo più semplice sarebbe solo di creare una struct Operand che contiene un double per lo scalare e un oggetto Vector per il vettore:

struct Operand
{
    double scalar_;
    Vector vector_;
    bool isVector_;
};

(È possibile impostare isVector_ a true se si tratta di un vettore operando, e falso se si tratta di un operando scalare)

Per lo stack effettivo, si può semplicemente utilizzare std::stack<Operand>.

Altre opzioni includono eredità (la creazione di tipi scalari e vettoriali derivate da un tipo di base di operando) o qualcosa di simile boost::variant, ma di qualcosa di semplice come questo, una struttura composizione come la Operand mostrato sopra è probabilmente il modo più semplice per farlo.

Altri suggerimenti

Hai guardato boost :: qualsiasi ?

Una soluzione è quella di utilizzare i sindacati. Con i sindacati, è possibile utilizzare lo stesso l'area di memoria per le diverse strutture. Ad esempio, si può avere uno struct matrimoniale e una in unione. Essi condividono la stessa memoria ed è possibile utilizzare solo uno di loro. È possibile utilizzare alcuni enum per dire quale usare.

I sindacati sono un po 'hacky, perché fanno uso di oggetti più complicato. Compilatore non sa come costruire, distruzione o copiare loro, perché molti oggetti possono condividere la stessa memoria. Ecco un piccolo esempio di come avrei fatto questo se mi piacerebbe risparmiare memoria (ok, enum prende quattro byte e quindi non è efficiente della memoria, ma cerchiamo di dimenticare che;)

#include <cstdlib>
#include <iostream>

struct Vector
{
    double x, y, z;
};

struct Element
{
    enum Type { SCALAR, VECTOR };
    Type type;
    union {
        double scalar;
        Vector v;
    } data;
};

int main(void)
{
    Element vector_element;
    vector_element.type = Element::VECTOR;
    vector_element.data.v.x = 1;
    vector_element.data.v.y = 2;
    vector_element.data.v.z = 3;

    Element scalar_element;
    scalar_element.type = Element::SCALAR;
    scalar_element.data.scalar = 3.142;

    std::cout << "The size of type Element without enum would be: " << (sizeof(Element) - sizeof(Element::Type)) << " bytes." << std::endl;

    return EXIT_SUCCESS;
}

A proposito, per qualche strana ragione, questo si traduce a 28 byte. Mi aspettavo 3 * 8 = 24 byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top