3

我用 C++ 设计了一个快速且基本的向量算术库。当我需要快速叉积或向量之间的角度时,我会从命令行调用程序。我不使用 Matlab 或 Octave 或相关的,因为启动时间大于计算时间。同样,这是针对非常基本的操作。

我正在扩展这个程序,并将它作为一个 RPN 计算器工作,用于以下类型的操作:

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

(给出一个向量,另一个向量和“交叉”运算符;吐出叉积)

堆栈必须接受 3d 向量或标量,用于以下操作:

1 2 3
2
*
out: 2 4 6

这个迷你计算器的词法分析器和解析器是微不足道的,但我似乎想不出一个创建内部堆栈的好方法。你将如何创建一个包含向量或双精度的堆栈(我汇总了我自己非常简单的向量类 - 不到一百行,它可以满足我的一切需要)。

如何创建一个接受 Vector 类或 double 类型元素的简单堆栈?

谢谢你。

4

3 回答 3

3

你看过boost::any吗?

于 2010-05-14T16:41:13.777 回答
3

一种解决方案是使用联合。使用联合,您可以为不同的结构使用相同的内存区域。例如,您可以在 union 中拥有一个 double 和一个 struct。它们共享相同的内存,您只能使用其中一个。您可以使用一些枚举来判断使用哪一个。

联合有点笨拙,因为它们使对象的使用更加棘手。编译器不知道如何构造、破坏或复制它们,因为许多对象可能共享相同的内存。这是一个小例子,如果我想节省内存,我将如何做到这一点(好吧,枚举需要四个字节,因此内存效率不高,但让我们忘记这一点;)

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

顺便说一句,由于某种奇怪的原因,这导致了 28 个字节。我预计 3 * 8 = 24 字节。

于 2010-05-14T17:08:35.803 回答
1

最简单的方法是创建一个Operand结构,其中包含一个double用于标量和一个Vector用于向量的对象:

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

(如果是向量操作数可以设置isVector_为真,如果是标量操作数可以设置为假)

对于实际的堆栈,您可以使用std::stack<Operand>.

其他选项包括继承(创建从操作数基类型派生的标量和向量类型)或类似的东西boost::variant,但对于像这样简单的东西,像Operand上面所示的组合结构可能是最简单的方法。

于 2010-05-14T16:34:01.640 回答