Обновить
0
0
Валерий Русаков @valerar

Аналитик

Отправить сообщение
Да, похоже вы правы.
Проблему со сборкой чисел можно решить на другом слое.

А вот это пожалуй не получится. В ОПН невозможно создать разрыв между этапами анализа очередного символа и формирования числа, будут потеряны опорные точки для такого формирования. А если это попробовать сделать со строкой до ОПН, то возникают неоправданные затраты.
Наверное вы правы. Просто я не понял предыдущего товарища.
Я не понял, что в результате делает алгоритм автора — вычисляет выражение?

Да, оба алгоритма вычисляют математическое выражения. Вход у обоих одинаков, как и выход. Разница в подходе к процессу.
«Алгоритм для ОПН взят из Wiki» и картинка под ним, выражение как раз не вычисляет, он служит для преобразования инфиксной нотации в постфиксную.

Там показан полный цикл расчёта по первой скобке (4 операнда и 3 операции внутри скобок). Показывать более длинный фрагмент смысла не имело. Конечный результат расчёта фрагмента — «r3».
Компиляция действительно решает все вопросы с математическими выражениями напрямую зашитыми в коде, но не решает задачи где надо получить результат из полученой из вне строки с заранее неизвестным составом операндов и операций.
В тексте программы вы можете писать как угодно — компилятор разберёт.
Ну а потом, здесь же никто никому ничего не навязывает. Вам удобно — здорово, пишите как удобно. Однако попробуйте всё же написать в ОПН конечное выражение предложенной в статье формулы: (A+B*C/D)+(E-F*((G/(H-J*(-1)+I)-L*(M-N)-R)+S)*W).
Ну и с посимвольным разбором естественно.
Вы не вполне правильно понимаете, как такое вычисляется. Предполагается, что арифметическое выражение в ОПН лежит в памяти (каждый операнд и операция в отдельной ячейке), а не в стеке.

Извините, но арифметическое выражение лежит в наборе символов определяемых как «строка». И я нигде не говорил о том, что всю строку кладут сразу в стек. ОПН — это посимвольный разбор строки с кучей выборов как действовать в зависимости от предыдущего символа. И даже не одного, минимум трёх: предыдущая операция, предыдущий символ (формирование чисел из цифр), счётчик скобок.
1. Если встретилось число, кладем его в стек;

В строке нет чисел, там есть цифры (символы). Так что чтобы собрать число из отдельных цифр, ну если только у вас не односимвольные числа, то перед помещением в стек число ещё собрать надо.
2. Если встретилась операция, достаем с вершины стека операнды для нее, вычисляем, результат кладем в стек.

Тоже не совсем так. Если вновь прибывшая операция приоритетнее предыдущей, то мы обязаны её положить в стек без каких-либо вычислений. Ну и другие нюансы.
Это очень экономный и быстрый алгоритм, в стеке лежит необходимый минимум данных: только результаты промежуточных вычислений, и никаких скобок и операций там нет.

И это утверждение достаточно спорно. Во-первых, на КАЖДЫЙ символ навешана куча логики. Во-вторых, работа со скобками никуда не девается. Более того она просто откладывается до закрытия скобкой фрагмента. Ну и т.д…
Попробуйте реализовать свои утверждения на листе бумаги и с карандашом хотя бы на двух уровнях вложения скобок и вещественными операндами. Полагаю, получите искреннее удовольствие.
1) сокращается длина выражения, так как нет лишних символов в виде скобок, короче текст программы

Длина подаваемой на вход строки не может сократиться — какая есть, такая и есть. Или вы имеете ввиду формулы которые и так обрабатываются на этапе компиляции.
2) нет разночтений в приоритете операций, об этом просто не нужно даже помнить, очередность исполнения определяется стеком, а не типом операции.

Приоритетность операций определяется математикой. Какие могут быть разночтения?
представьте себе строку длинной в один миллион символов и сто тысяч пар скобок.
Хвост строки придется перемещать столько же раз.

Представил. Если формула конечна и помещается в памяти, то проблем не вижу.
Ну и не понял причём тут хвост строки. Строка укорачивается по мере расчёта фрагментов замещением фрагмента на рассчитанное значение. Как раз в этом отличий в алгоритмах нет.
Имелась ввиду строчка: A+B*(C — D/(E + F)) преобразованная в «ABCDEF±*+ » — именно она является последней в приведённой таблице.
Ну а подоставать из стека, можно предварительно туда положив, я оставляю вам. Думаю на уровне реальных действий вам будет о-о-очень интересно.
Целиком и полностью согласен.
Не понял. Это указание на какую-то ошибку или предложение что-то объяснить?
На всякий случай — алгоритм тестировался на формулах типа: -2.5*(10+12)-(20.5+(2*(3/6-5)*2+10/5))+100+((10.2+12.8)*2/4-5+[log10|100|]*[sqrt|4|]+[pow|2;3|])

Информация

В рейтинге
Не участвует
Откуда
Новосибирск, Новосибирская обл., Россия
Дата рождения
Зарегистрирован
Активность