|
|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Oleg Tynianyi 2:5025/900 29 May 2001 11:50:00 To : All Subject : Re: Синтаксический анализатор --------------------------------------------------------------------------------
>
> Дана строка, например:
>
> 1+428-cos3*8-(sin(0.1-0.01)*(2+2)
>
> Ее надо вычислить. Строка типа String, может менятся длина и содержание...
> With Respect, Yuri Turchin.
>
> ЗЫ: Hадо срочно! Очень! Вообще голову заклинило, торможу...
Hу вообще-то все просто:
Теория: выражение состоит из операций, каждая из которых оперирует с 1,2,..N
операндами.
Практика: пишешь цикл, в каждом обороте цикла выделяешь последовательно
следующую лексемму,
коей является слово или значек (*/-+()%). Далее так: строишь дерево, на
одном уровне располагаются
операции, выполняемые последовательно, при этом операнды равнозначны.
Для твоего выражения это: 1 428 (cos3*8) (sin(0.1-0.01)*(2+2), итого
всего их 4 штуки разделенных пробелами. А между ними операции + - - то есть
их три. Далее для узлов дерева 2 и 3 есть нижние уровни.
Признаком перехода на более низкий уровень является открывающаяся скобка,
признаком возврата на более верхний - закрывающаяся скобка. Плюс добавь сюда
приоритет операций. Сначала раздели все
на простые операции типа +-*/, а потом для операций */ введи дополнительные
скобки для унификации.
Таким образом твое выражение разложится в:
1 + 428 - ( ) - ( )
cos * 8 sin( ) * ( )
0.1 - 0.01 2 + 2
Как видишь все свелось к простым арифметическим действиям и паре вызовов
функции.
А вот вычисления по такому дереву лучше всего реализовать в виде обычной
рекурсивной функции:
как только у узла есть поддерево - сначала уходишь в него, а потом уже
считаешь сам узел.
Олег
--- Microsoft Outlook Express 5.50.4133.2400
* Origin: Comment is superfluous... (2:5025/900@fidonet)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/1338439d7f74b.html, оценка из 5, голосов 10
|