Стек C ++ для нескольких типов данных (векторный калькулятор RPN) - PullRequest
3 голосов
/ 14 мая 2010

Я разработал быструю и базовую векторную арифметическую библиотеку на C ++. Я вызываю программу из командной строки, когда мне нужно быстрое перекрестное произведение или угол между векторами. Я не использую Matlab или Octave или связанные с ними, потому что время запуска больше, чем время вычислений. Опять же, это для очень простых операций.

Я расширяю эту программу и заставлю ее работать как калькулятор RPN для операций типа:

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

(указать один вектор, другой вектор и оператор "крест"; выпустить перекрестное произведение)

Стек должен принимать трехмерные векторы или скаляры для таких операций, как:

1 2 3
2
*
out: 2 4 6

Лексер и парсер для этого мини-калькулятора тривиальны, но я не могу придумать хорошего способа создания внутреннего стека. Как бы вы создали стек для размещения векторов или двойников (я свернул свой собственный очень простой векторный класс - менее ста строк, и он делает все, что мне нужно).

Как мне создать простой стек, который принимает элементы класса Vector или типа double?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 14 мая 2010

Вы смотрели на boost :: any ?

3 голосов
/ 14 мая 2010

Одним из решений является использование союзов.Союзы, вы можете использовать одну и ту же область памяти для разных структур.Например, у вас может быть одна двойная и одна структура в объединении.Они разделяют одну и ту же память, и вы можете использовать только один из них.Вы можете использовать некоторое перечисление, чтобы указать, какой из них использовать.

Союзы немного глупы, потому что они делают использование объектов более хитрым.Компилятор не знает, как создавать, разрушать или копировать их, потому что многие объекты могут совместно использовать одну и ту же память.Вот небольшой пример того, как я мог бы сделать это, если бы я хотел сэкономить память (хорошо, enum занимает четыре байта и, следовательно, неэффективно использует память, но давайте забудем об этом;)по какой-то странной причине это приводит к 28 байтам.Я ожидал 3 * 8 = 24 байта.

1 голос
/ 14 мая 2010

Самый простой способ - создать Operand структуру, содержащую double для скаляра и Vector объект для вектора:

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

(вы можете установить isVector_ в true, если это векторный операнд, и в false, если это скалярный операнд)

Для реального стека вы можете просто использовать std::stack<Operand>.

Другие опции включают наследование (создание скалярных и векторных типов, полученных из базового типа операнда) или что-то вроде boost::variant, но для чего-то простого, подобного этому, составная структура, такая как Operand, показанная выше, вероятно, самый простой способ сделай это.

...