Ещё одно вычисление выражений
Задачка кажется не очень сложной, даже, если не знать как её делать (я не знал). Целью является быстрое вычисление чего-то типа 4 * ( 5 + 7 ^ 4)
. Для это я парсил исходную строку в список токенов, а затем непосредственно вычислял, что получится.
Я решил, что проще всего будет реализовать (а мне потом и понять) алгоритм, когда после каждого действия будет выполняться некий “хороший” инвариант. Первое что приходит в голову — это то, что истинность выражение после выполнения операции не меняется (TITO соблюдается). То есть выражение 3 + 5
можно заменить на 8
или хотя бы на 4 * 2
.
Непосредственно сама обработка является несколькими проходами, так что в каждом проходе мы избавляемся от операций одного приоритета. 4 + 5 * 3
заменяется на 4 + 15, 7 - 5 * 2^3
заменяется на 7 - 5*8
. Таким образом, каждый цикл тривиален, и легко задавать приоритеты операций.
Если использовать один список как контейнер для токенов и при работе изменять непосредственно его, сохраняя указанные инварианты, то сложность получается \(O\left( N \right)\), где \(N\) — число токенов.
Времени на непосредственно кодирование ушло часа три-четыре, но в это время не входит продумывание мелких деталей.
Всё написано на C++11. Исходники лежат на GitHub и BitBucket.