Пытаюсь написать программу, выполняющую преобразование выражение в бесскобочный вид (обратная польская нотация). Всё, вроде бы, работает, но при обработке выражения "(А+Б)*(В+Г)-Д" пропадает минус, который в результате должен оказаться в конце. Подскажите, где ошибка?
Код | ОТДЕЛ ОПЗ+; ИСПОЛЬЗУЕТ Знак ИЗ "...\Отделы\Иное\", Вывод ИЗ "...\Отделы\Обмен\";
ПЕР Стек: РЯД 20H ИЗ ЗНАК; р1, р2: РЯД 16 ИЗ ЗНАК;
ЗАДАЧА Преимущество(зн: ЗНАК): ЦЕЛ; УКАЗ ВЫБРАТЬ зн ИЗ '*', '/': ВОЗВРАТ 3 | '-', '+': ВОЗВРАТ 2 | '(', ')': ВОЗВРАТ 1 ИНАЧЕ ВОЗВРАТ 0 КОН КОН Преимущество;
ЗАДАЧА Добавить(зн: ЗНАК); УКАЗ ЕСЛИ ДЛИНА(Стек) = РАЗМЕР(Стек) ТО Вывод.Цепь("Ошибка: стек переполнен."); СТОП(0) КОН; Стек[ДЛИНА(Стек)] := зн КОН Добавить;
ЗАДАЧА Удалить(): ЗНАК; ПЕР зн: ЗНАК; УКАЗ ЕСЛИ ДЛИНА(Стек) = 0 ТО Вывод.Цепь("Ошибка: стек пуст."); СТОП(0) КОН; зн := Стек[ДЛИНА(Стек)-1]; Стек[ДЛИНА(Стек)-1] := 0X; ВОЗВРАТ зн КОН Удалить;
ЗАДАЧА Перевести(вход-, выход+: РЯД ИЗ ЗНАК); ПЕР сч1, сч2: УЗКЦЕЛ; зн: ЗНАК; УКАЗ зн := 0X; сч2 := 0; ОТ сч1 := 0 ДО ДЛИНА(вход)-1 ВЫП ЕСЛИ вход[сч1] = ")" ТО ПОКА Стек[ДЛИНА(Стек)-1] # "(" ВЫП выход[сч2] := Удалить(); УВЕЛИЧИТЬ(сч2) КОН; зн := Удалить() АЕСЛИ Знак.Буква(вход[сч1]) ТО выход[сч2] := вход[сч1]; УВЕЛИЧИТЬ(сч2) АЕСЛИ вход[сч1] = "(" ТО Добавить(вход[сч1]) АЕСЛИ (вход[сч1] = "+") ИЛИ (вход[сч1] = "-") ИЛИ (вход[сч1] = "/") ИЛИ (вход[сч1] = "*") ТО ЕСЛИ ДЛИНА(Стек) = 0 ТО Добавить(вход[сч1]) ИНАЧЕ ЕСЛИ Преимущество(вход[сч1]) > Преимущество(Стек[ДЛИНА(Стек)-1]) ТО Добавить(вход[сч1]) ИНАЧЕ ПОКА (ДЛИНА(Стек) # 0) И (Преимущество(вход[сч1]) <= Преимущество(Стек[ДЛИНА(Стек)-1])) ВЫП выход[сч2] := Удалить(); УВЕЛИЧИТЬ(сч2) КОН; Добавить(выход[сч1]) КОН КОН КОН КОН; ПОКА ДЛИНА(Стек) # 0 ВЫП выход[сч2] := Удалить(); УВЕЛИЧИТЬ(сч2) КОН КОН Перевести;
УКАЗ р1 := "(А+Б)*(В+Г)-Д"; Перевести(р1, р2); Вывод.Цепь(р2)
КОН ОПЗ. |
|