C++多种数据类型的堆栈(RPN向量计算器)

发布于 2024-09-01 18:01:24 字数 487 浏览 0 评论 0原文

我用 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 类型元素的简单堆栈?

谢谢。

I have designed a quick and basic vector arithmetic library in C++. I call the program from the command line when I need a rapid cross product, or angle between vectors. I don't use Matlab or Octave or related, because the startup time is larger than the computation time. Again, this is for very basic operations.

I am extending this program, and I will make it work as an RPN calculator, for operations of the type:

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

(give one vector, another vector, and the "cross" operator; spit out the cross product)

The stack must accept 3d vectors or scalars, for operations like:

1 2 3
2
*
out: 2 4 6

The lexer and parser for this mini-calculator are trivial, but I cannot seem to think of a good way for creating the internal stack. How would you create a stack of for containing vectors or doubles (I rolled up my own very simple vector class - less than one hundred lines and it does everything I need).

How can I create a simple stack which accepts elements of class Vector or type double?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪之魂 2024-09-08 18:01:25

您看过 boost::any 吗?

Have you looked at boost::any?

忆沫 2024-09-08 18:01:25

一种解决方案是使用工会。通过联合,您可以对不同的结构使用相同的内存区域。例如,联合中可以有一个双精度型和一个结构体。它们共享相同的内存,并且您只能使用其中之一。您可以使用一些枚举来告诉使用哪一个。

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

#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 字节。

One solution is to use unions. With unions, you can use same the memory area for different structs. For example, you can have one double and one struct in union. They share the same memory and you can only use one of them. You can use some enum to tell which one to use.

Unions are a bit hacky, because they make usage of objects trickier. Compiler does not know how to construct, destruct or copy them, because many objects may share the same memory. Here is a little example how I would do this if I would like to save memory (okay, enum takes four bytes and thus is not memory efficient, but let's forget that ;)

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

By the way, for some strange reason, this results to 28 bytes. I expected 3 * 8 = 24 bytes.

双手揣兜 2024-09-08 18:01:25

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

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

您可以如果是向量操作数,则将 isVector_ 设置为 true,如果是标量操作数则设置为 false)

对于实际堆栈,您可以只使用 std::stack

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

The simplest way would be just to create an Operand struct that contains a double for the scalar and a Vector object for the vector:

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

(you can set isVector_ to true if it is a vector operand, and false if it is a scalar operand)

For the actual stack, you can just use std::stack<Operand>.

Other options include inheritance (creating scalar and vector types derived from an operand base type) or something like boost::variant, but for something simple like this, a composition struct like the Operand shown above is probably the easiest way to do it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文