24591: 中序表达式转后序表达式
http://cs101.openjudge.cn/practice/24591/
中序表达式是运算符放在两个数中间的表达式。乘、除运算优先级高于加减。可以用"()"来提升优先级 --- 就是小学生写的四则算术运算表达式。中序表达式可用如下方式递归定义:
1)一个数是一个中序表达式。该表达式的值就是数的值。
- 若a是中序表达式,则"(a)"也是中序表达式(引号不算),值为a的值。
- 若a,b是中序表达式,c是运算符,则"acb"是中序表达式。"acb"的值是对a和b做c运算的结果,且a是左操作数,b是右操作数。
输入一个中序表达式,要求转换成一个后序表达式输出。
输入
第一行是整数n(n<100)。接下来n行,每行一个中序表达式,数和运算符之间没有空格,长度不超过700。
输出
对每个中序表达式,输出转成后序表达式后的结果。后序表达式的数之间、数和运算符之间用一个空格分开。
样例输入
3
7+8.3
3+4.5*(7+2)
(3)*((3+4)*(2+3.5)/(4+5))样例输出
7 8.3 +
3 4.5 7 2 + * +
3 3 4 + 2 3.5 + * 4 5 + / *来源: Guo wei
Shunting Yard 算法是一种用于将中缀表达式转换为后缀表达式的算法。它由荷兰计算机科学家 Edsger Dijkstra 在1960年代提出,用于解析和计算数学表达式。
Shunting Yard 算法的主要思想是使用两个栈(运算符栈和输出栈)来处理表达式的符号。算法按照运算符的优先级和结合性,将符号逐个处理并放置到正确的位置。最终,输出栈中的元素就是转换后的后缀表达式。
以下是 Shunting Yard 算法的基本步骤:
- 初始化运算符栈和输出栈为空。
- 从左到右遍历中缀表达式的每个符号。
- 如果是操作数(数字),则将其添加到输出栈。
- 如果是左括号,则将其推入运算符栈。
- 如果是运算符:
- 如果运算符的优先级大于运算符栈顶的运算符,或者运算符栈顶是左括号,则将当前运算符推入运算符栈。
- 否则,将运算符栈顶的运算符弹出并添加到输出栈中,直到满足上述条件(或者运算符栈为空)。
- 将当前运算符推入运算符栈。
- 如果是右括号,则将运算符栈顶的运算符弹出并添加到输出栈中,直到遇到左括号。将左括号弹出但不添加到输出栈中。
- 如果还有剩余的运算符在运算符栈中,将它们依次弹出并添加到输出栈中。
- 输出栈中的元素就是转换后的后缀表达式。
python
def infix_to_postfix(expression):
precedence = {'+':1, '-':1, '*':2, '/':2}
stack = []
postfix = []
number = ''
for char in expression:
if char.isnumeric() or char == '.':
number += char
else:
if number:
num = float(number)
postfix.append(int(num) if num.is_integer() else num)
number = ''
if char in '+-*/':
while stack and stack[-1] in '+-*/' and precedence[char] <= precedence[stack[-1]]:
postfix.append(stack.pop())
stack.append(char)
elif char == '(':
stack.append(char)
elif char == ')':
while stack and stack[-1] != '(':
postfix.append(stack.pop())
stack.pop()
if number:
num = float(number)
postfix.append(int(num) if num.is_integer() else num)
while stack:
postfix.append(stack.pop())
return ' '.join(str(x) for x in postfix)
n = int(input())
for _ in range(n):
expression = input()
print(infix_to_postfix(expression))python
import re
def expProcessor(fpexp):
temp = re.findall('[0-9.a-zA-Z]+|[**]+|[//]+|[+\-*/()]?|[not]?|[and]?|[or]?|[True]?|[False]?|.',\
fpexp)
fplist = [i for i in temp if i not in ["", " "]]
i = 1
while i < len(fplist):
if (fplist[i] == "-") and (fplist[i - 1] in ["(", "+", "-", "*", "/", "**", "//", "not", "and", "or"]):
fplist[i + 1] = "-" + fplist[i + 1]
fplist.pop(i)
else:
i += 1
return fplist
def priority(x):
if x == '*' or x == '/':
return 2
if x == '+' or x == '-':
return 1
return 0
def is_numeric(string):
try:
int(string)
return True
except ValueError:
try:
float(string)
return True
except ValueError:
return False
def infix_trans(infix):
postfix = []
op_stack = []
for char in infix:
if is_numeric(char):
postfix.append(char)
else:
if char == '(':
op_stack.append(char)
elif char == ')':
while op_stack and op_stack[-1] != '(':
postfix.append(op_stack.pop())
op_stack.pop()
else:
while op_stack and priority(op_stack[-1]) >= priority(char) and op_stack[-1] != '(':
postfix.append(op_stack.pop())
op_stack.append(char)
while op_stack:
postfix.append(op_stack.pop())
return postfix
n = int(input())
for _ in range(n):
s = input()
fp = expProcessor(s)
pp = infix_trans(fp)
print(' '.join(pp))python
def infix_to_postfix(expression):
def get_precedence(op):
precedences = {'+': 1, '-': 1, '*': 2, '/': 2}
return precedences[op] if op in precedences else 0
def is_operator(c):
return c in "+-*/"
def is_number(c):
return c.isdigit() or c == '.'
output = []
stack = []
number_buffer = []
def flush_number_buffer():
if number_buffer:
output.append(''.join(number_buffer))
number_buffer.clear()
for c in expression:
if is_number(c):
number_buffer.append(c)
elif c == '(':
flush_number_buffer()
stack.append(c)
elif c == ')':
flush_number_buffer()
while stack and stack[-1] != '(':
output.append(stack.pop())
stack.pop() # popping '('
elif is_operator(c):
flush_number_buffer()
while stack and get_precedence(c) <= get_precedence(stack[-1]):
output.append(stack.pop())
stack.append(c)
flush_number_buffer()
while stack:
output.append(stack.pop())
return ' '.join(output)
# Read number of expressions
n = int(input())
# Read each expression and convert it
for _ in range(n):
infix_expr = input()
postfix_expr = infix_to_postfix(infix_expr)
print(postfix_expr)