la pile de C pour de multiples types de données (calculateur de vecteur RPN)

StackOverflow https://stackoverflow.com/questions/2835847

  •  26-09-2019
  •  | 
  •  

Question

J'ai conçu une bibliothèque arithmétique vecteur rapide et de base en C ++. J'appelle le programme à partir de la ligne de commande quand je besoin d'un produit croisé rapide, ou l'angle entre les vecteurs. Je ne me Matlab ou Octave ou connexes, parce que le temps de démarrage est plus grand que le temps de calcul. Encore une fois, cela est pour les opérations très simples.

Je prolonge ce programme, et je vais le faire fonctionner comme une calculatrice RPN, pour les opérations du type:

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

(donner un vecteur, un autre vecteur, et l'opérateur « croix »; recracher le produit vectoriel)

La pile doit accepter des vecteurs 3D ou scalaires, pour des opérations telles que:

1 2 3
2
*
out: 2 4 6

L'analyseur et pour lexer ce mini-calculatrice sont trivial, mais je ne peux pas sembler penser à une bonne façon de créer la pile interne. Comment voulez-vous créer une pile de vecteurs pour contenir ou doubles (je roulais ma propre très simple classe vecteur - moins d'une centaine de lignes et il fait tout ce que je besoin).

Comment puis-je créer une pile simple qui accepte les éléments de classe Vector ou type à double?

Merci.

Était-ce utile?

La solution

La façon la plus simple serait juste de créer un struct Operand qui contient un double pour le scalaire et un objet Vector pour le vecteur:

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

(vous pouvez définir isVector_ true si elle est un vecteur opérande, et faux si elle est un opérande scalaire)

Pour la pile réelle, vous pouvez simplement utiliser std::stack<Operand>.

D'autres options incluent l'héritage (la création de types scalaire et vectoriel dérivés d'un type de base d'opérande) ou quelque chose comme boost::variant, mais pour simple quelque chose comme ça, une struct composition comme le Operand ci-dessus est probablement la meilleure façon de le faire.

Autres conseils

Avez-vous regardé boost :: any ?

Une solution est aux syndicats d'utilisation. Avec les syndicats, vous pouvez utiliser même la zone de mémoire pour les différentes structures. Par exemple, vous pouvez avoir un struct double et une en union. Ils partagent la même mémoire et vous ne pouvez utiliser l'un d'entre eux. Vous pouvez utiliser une ENUM pour dire lequel utiliser.

Les syndicats sont un peu hacky, parce qu'ils font usage de plus délicat des objets. Compilateur ne sait pas comment construire, détruire ou de les copier, parce que de nombreux objets peuvent partager la même mémoire. Voici un petit exemple comment je ferais cela si je voudrais économiser de la mémoire (ok, ENUM prend quatre octets et est donc pas efficace de la mémoire, mais nous allons oublier que;)

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

Par ailleurs, pour une raison étrange, ce résultat à 28 octets. Je m'y attendais 3 * 8 = 24 octets.

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