Есть QString со случайным арифметическим выражением.
Надо вынуть его из строки и посчитать по правилам арифметики.
Например:
1 + 2 * 3 / 4 - 5
2 * 3 = 6
6 / 4 = 1.5
1.5 + 1 = 2.5
2.5 -5 = -2.5
Уже часа два сижу и выдумываю алгоритм - итог почти нулевой.
Если будут какие-нибудь соображения, пожалуйста делитесь, а я пока буду дальше скрипеть.
Арифметика (Qt)
Модератор: Модераторы разделов
-
- Сообщения: 842
- Статус: Местный "тролль"
- ОС: Fedora
Арифметика
Жестокий стоячий админ (с) коллега
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Арифметика
курить до достижения просветления косяк ScriptEngine::evaluate() и все что с этим связано в разных смесях.
имха.
(а косяк ещё тот, забористый. меня вот уже 3 недели не отпускает )
ну а в принципе, можно построить синтаксический анализатор на основе рекурсивных описаий типов. За вечер можно написать.
тоже вставляет конкретно.
(если не знаете что это - найдите драгдилера и закупите у него книжку от Г. Шилдт "Теория и практика C++"
- там есть описания интерпретатора для языка Small Basic и функции для разбора выражений)
имха.
(а косяк ещё тот, забористый. меня вот уже 3 недели не отпускает )

ну а в принципе, можно построить синтаксический анализатор на основе рекурсивных описаий типов. За вечер можно написать.
тоже вставляет конкретно.

(если не знаете что это - найдите драгдилера и закупите у него книжку от Г. Шилдт "Теория и практика C++"
- там есть описания интерпретатора для языка Small Basic и функции для разбора выражений)
-
- Сообщения: 283
- ОС: Slackware 12.2
Re: Арифметика
Может это поможет:
http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%...%B8%D1%81%D1%8C
Сам решал, так:
выполнял сначала действия в скобках рекурсивно вызывая функцию,
потом по indexOf брал первую из * и / и сравнивал, какой из них меньше, тот что первый выполнял и перезаписывал строку.
Повторял, пока оставались * или / потом переходил на сложение и вычитание. /*правда писал на Java*/
Правда скорее всего придется в случае если есть = разбить выражение на два подвыражения. Решал в лоб, так что не серчайте, если что не так.
http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%...%B8%D1%81%D1%8C
Сам решал, так:
выполнял сначала действия в скобках рекурсивно вызывая функцию,
потом по indexOf брал первую из * и / и сравнивал, какой из них меньше, тот что первый выполнял и перезаписывал строку.
Повторял, пока оставались * или / потом переходил на сложение и вычитание. /*правда писал на Java*/
Правда скорее всего придется в случае если есть = разбить выражение на два подвыражения. Решал в лоб, так что не серчайте, если что не так.
Ich weiss, dass ich nichts weiss, aber wissen Sie es auch?
Завистники на что не взглянут,
подымут вечно лай,
А ты себе своей дорогою ступай,
Полают, да отстанут. Крылов
Завистники на что не взглянут,
подымут вечно лай,
А ты себе своей дорогою ступай,
Полают, да отстанут. Крылов
-
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Арифметика
Классика жанра - алгоритм Дейкстры для перевода в упомянутую уже 'обратную польскую запись', а потом собственно вычисление на стековой машине (типа как вычисление в математическом сопроцессоре устроено).
Про обратную польскую нотацию (ОПН) и алгоритм Дейкстры найдёте в википедии. Получается что-то такое:
1 + 2 * 3 / 4 - 5 --> 1 2 3 * 4 / + 5 -
Вычисление организуется так: идём по строке в ОПН слева направо. Если очередной символ (лексема) - число, то кладём его на стек (push). Если не число, а бинарный оператор (+, например), то снимаем со стека два числа, производим над ними соответствующее действие и результат кладём обратно на стек. К концу строки на стеке остаётся ровно одно число - это и есть результат вычисления.
Про обратную польскую нотацию (ОПН) и алгоритм Дейкстры найдёте в википедии. Получается что-то такое:
1 + 2 * 3 / 4 - 5 --> 1 2 3 * 4 / + 5 -
Вычисление организуется так: идём по строке в ОПН слева направо. Если очередной символ (лексема) - число, то кладём его на стек (push). Если не число, а бинарный оператор (+, например), то снимаем со стека два числа, производим над ними соответствующее действие и результат кладём обратно на стек. К концу строки на стеке остаётся ровно одно число - это и есть результат вычисления.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
- Сообщения: 842
- Статус: Местный "тролль"
- ОС: Fedora
Re: Арифметика
Благодарю. Алгоритм в общих чертах ясен. Завтра на свежую голову лабать буду.
Жестокий стоячий админ (с) коллега
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Арифметика
А у вас задание такое - самому реализовать алгоритм вычисления или вам просто надо "вычислить что в строке написано"?
Если просто вычислять - то проще всего так (начало раскурки косяка ScriptEngine::evaluate() ):
Если просто вычислять - то проще всего так (начало раскурки косяка ScriptEngine::evaluate() ):
Код: Выделить всё
#include <QApplication>
#include <QLabel>
#include <QtScript>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QScriptEngine engine;
QLabel ResultLabel = QLabel ( engine.evaluate("2+4*5").toString() );;
ResultLabel.show();
return app.exec();
}
-
- Сообщения: 842
- Статус: Местный "тролль"
- ОС: Fedora
Re: Арифметика
Denjs, это пять! Классная весч этот QtScriptEngine, обязательно покурю. Спасибо за информацию.
Жестокий стоячий админ (с) коллега
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Арифметика
а я-ж что говорю! это ещё тот косяк! там ещё достаточно полновесный ООП язык и доступ к избранным объектам программы в придачу!
прямые поставки со специальных плантаций троллей где самая сочная трава и самые вкусные грибочки!

пару раз затянешься - не отпустит до конца года. я просто пищу от восторга!
