Вход


Главная страница >> Учебный процесс >> Задачник >> Олимпиадные задачи (с решениями) >> СТРУКТУРЫ ДАННЫХ. >> Номер 17

[Назад]    [Содержание ]    [Вперед]

  


Номер 17


  Условие: Номер 17


Задача 16. Вводится скобочное арифметическое выражение. В выражении могут встречаться открывающая и закрывающая круглые скобки (и), знаки операций +, -, *, / (деление - целочисленное) и цифры от 0 до 9. Найти значение этого скобочного выражения. Пример: '(3+5*2)/3-1'=3.

  Решение задачи: Номер 17


Решение задачи 16. Для упрощения вычислений рассмотрите преобразование выражения в обратную польскую запись, т.е. в такую бесскобочную форму, в которой операнды записываются в том же порядке, что и в исходном выражении, а каждый знак операции следует непосредственно за операндами, над которыми эта операция проводится. Пример: Выражение '(3+5*2)/3-1' преобразуется в '3 5 2 * + 3 / 1 -' (сначала будет выполняться операция * над предыдущими двумя операндами 5 и 2, результат 10 помещается на место чисел 5 и 2. Затем - операция + над предыдущими двумя операндами 3 и 10, результат 13 помещается на место 3 и 10, и т.д. Выражение в ходе вычисления будет принимать вид: 3 5 2 * + 3 / 1 - 3 10 + 3 / 1 - 13 3 / 1 - 4 1 - 3. Алгоритм вычисления скобочного арифметического выражения. Преобразуем сначала выражение в обратную польскую запись. Каждой операции и открывающей скобке припишем приоритет: Приоритет ( 0 +,- 1 *,/ 2 Пустой стек 0 Шаг 1. Если во входной строке нет литер, то перейти к шагу 6; иначе прочитать следующий элемент (скобку, операцию или операнд) и обозначить его через x. Шаг 2. Если x - операнд, то перенести его в выходную строку, поместить вслед за ним разделитель и вернуться у шагу 1. Шаг 3. Если x - открывающая скобка, то поместить ее в стек и вернуться к шагу 1. Если x - закрывающая скобка, то перейти к шагу 4; иначе перейти к шагу 5. Шаг 4. Если элемент, находящийся на вершине стека, не является открывающей скобкой, то перенести его из стека в выходную строку, поместить за ним разделитель, а затем повторить шаг 4. Если на вершине стека находится открывающая скобка, удалить ее из стека и вернуться к шагу 1. Шаг 5. Если приоритет элемента на вершине стека не меньше приоритета x, то перенести этот элемент из стека в выходную строку, поместить за ним разделитель, а затем повторить шаг 5. Иначе поместить x на вершину стека и вернуться к шагу 1. Шаг 6. Освободить стек, удаляя каждый раз по одному элементу и помещая его в выходную строку с последующим разделителем. Закончить работу. Пример: Этот алгоритм переводит выражение '(3+5*2)/3-1' в '3 5 2 * + 3 / 1 -'. Если в ходе построения обратной польской записи не переносить знак операции в выходную строку (где он бы стоял непосредственно за теми операндами, над которыми должна выполняться эта операция), а взять из выходной строки два последних операнда, выполнить над ними операцию, и результат поместить снова в выходную строку, то у нас после шага 6 в выходной строке окажется искомый результат. Рассмотрим вычисления на примере выражения (3+5*2)/3-1 Очередной элемент входной строки После обработки элемента стек выходная строка ( ( Пустая 3 ( 3 + ( + 3 5 ( + 3 5 * ( + * 3 5 2 ( + * 3 5 2 ) Пуст Вместо переноса знака * в выходную строку, мы выполняем умножение над двумя последними элементами выходной строки, при этом 5 и 2 из нее извлекаются, а результат умножения 10 - помещается в выходную строку. Она принимает вид: 3 10. Далее мы должны были бы перенести знак + из стека в выходную строку, но вместо этого опять же выполняем сложение над двумя последними элементами и результат помещаем в выходную строку, так что она становится следующей: 13 / / 13 3 / 13 3 - - Выполняем деление 13 на 3 Результат в выходную строку 4 1 - 4 1 входная строка пустая пуст В выходную строку помещаем результат 4-1=3. Это и есть значение выражения Естественно в место выходной строки использовать стек чисел. Операции проводятся над двумя верхними элементами стека. Результат снова помещается в стек.

Назад



[Назад]    [Содержание ]    [Вперед]

  


  
За содержание страницы отвечает Гончарова М.Н.
©
Кафедра СПиКБ, 2002-2017