ЗАДАЧА 'Калькулятор'. Составить алгоритм, проверяющий правильность алгебраического выражения с переменными и вычисляющий его значение при конкретных значениях переменных. Соображения по решению задачи. Рассмотрим синтаксический анализ введенного выражения. Правильность расстановки скобок проверяем по алгоритму Рутис- хаузера: значение специальной переменной увеличивается на единицу при прохождении открывающей скобки и уменьшается на единицу при прохождении закрывающей скобки. если первоначальное значение пере- менной было 0, то скобки расставлены верно тогда и только тогда, когда в процессе просмотра значение переменной не становилось от- рицательным, а конечное значение есть 0. Выражение верно, если верно расставлены скобки и последова- тельность символов не нарушает диаграмму (выражение предварительно заключаем в скобки): ┌──────────────────<знак операции>──────────┐  │ ───┴─┬───────────────────┬<операнд>─┬────────┬─┴──────  │  │ ├─< - >─┬─< ( >──┘ └─< ) >─┘ └───────┘ Операнд - число или переменная. Число должно начинаться и кончаться цифрой и состоять из цифр и десятичных точек. Точек должно быть не больше одной. Переменная должна начинаться латинской буквой или символом подчеркивания и может содержать латинские буквы, символы подчерки- вания и цифры. Заведем массив, в котором будем хранить имена пере- менных. Выделив имя переменной, если его еще нет в массиве, зано- сим туда. Значения переменных запрашиваем и храним в массиве паралель- ном первому. Рассмотрим вычисление значения корректного выражения. При синтаксическом анализе все унарные минусы заменяем на '$', чтобы однозначно отличать их от операции вычитания. Определим приоритеты операций так: ')' - 1, '(' - 2, '+' и '-' - 3, '*' и '/' - 4, '$' - 5. Заведем два стека - стек операций и стек результата. Далее просматриваем выражение слева направо (напомним, что все выражение заключено в скобки): 1) встретив латинскую букву или символ подчеркивания, выделим имя переменной и занесем ее значение в стек результата; 2) встретив цифру, выделим число и занесем его в стек резуль- тата; 3) встретив знак операции, кроме унарного минуса, извлекаем из стека операций и выполняем операции, имеющие приоритет не мень- ший, чем у встреченного знака (выполнение операции заключается в извлечении двух операндов из стека результата, применении к ним операции и занесении результата в стек результата), затем заносим встреченный знак операции в стек операций; 4) встретив открывающую скобку, заносим ее в стек операций; 5) встретив закрывающую скобку, извлекаем из стека операций и выполняем операции до тех пор, пока не извлечем открывающую скоб- ку; 6) встретив унарный минус, заносим его в стек операций. Заметим, что выполнение унарного минуса отличается тем, что операция применяется к одному операнду, который извлекается из стека результата. При выполнении бинарных операций операцию подс- тавляем между операндом, извлеченным из стека результата вторым, и операндом, извлеченным первым. По окончании просмотра выражения в стеке результата останется единственное значение - значение выражения. Дополнения: 1) При выполнении деления контролируем деление на ноль. 2) Исходя из максимальной длины вводимой строки 255 символов, задаем стек операций глубиной 127 и стек результата глубиной 86 (для выражений вида 4-4*(4-4*(4-4*(...4-4*(4-4*(4-4*4))...))) ), массивы под переменные заводим, рассчитывая максимум на 95 пере- менных (для выражений вида a+b+c+...+y+z+aa+ab+ +ac+... ). 3) Рассмотрим вычисление выражения на примере (2*(3*4-7)+6). последовательность заполнения стеков будет следующей (операнды стека результата для наглядности заключены в скобки): стек результата (2)(3)(4) │ (2)(12)(7) │ (2)(5) │ (10)(6) │ (16) стек операций (*(* │ (*(- │ (* │ (+ │