Dijkstra 调车场算法的实施在某些情况下无法正常工作
Implementation of Dijkstra's Shunting Yard Algorithm not working properly for some cases
我正在尝试将 Dijkstra 的调车场算法 实施到 python,因为这将是一个很好的练习。但是,即使我的代码对于某些测试用例也能正常工作。其中一些无法正常工作。
在我的具体情况下,在我在图片中显示的位置之后无法正常工作:screenshot
这是我的代码:
operator_dict = {"^": 3,
"*": 2,
"/": 2,
"+": 1,
"-": 1,
#"(": 0,
#")": 8
}
parenthesis_dict = {
"(":1,
")":0
}
operator_assoc = {"^": 1, # right
"*": 0, # left
"/": 0,
"+": 0,
"-": 0,
"(": 0,
")": 0,
}
test1 = "A-B^C^D*(E-(F-G-H))/K"
test2 = "A*B+C-D"
test3 = "A-B*(C-D-E)/F-G"
from time import sleep
initial_expression = test1
stack = []
output_queu = []
# if it is an operand we push it to the output queu
def operand_check(element):
if (element not in operator_dict.keys()) and (element not in parenthesis_dict.keys()):
output_queu.append(element)
def parenthesis_check(element):
# push down the left parenthesis
if element == "(":
stack.append(element)
# if it's right parenthesis then pop everything out of stack until
# you reach left parenthesis
elif element == ")":
while stack[-1] != "(":
temp = stack.pop()
output_queu.append(temp)
# to remove left parenthesis
stack.remove(stack[-1])
def operator_check(element):
if element in operator_dict.keys():
while (len(stack) != 0) and assoc_precedence_check(element) and does_top_of_stack_have_operator():
temp = stack.pop()
output_queu.append(temp)
stack.append(element)
def assoc_precedence_check(element):
if stack[-1] == "(" or ((operator_assoc[element] == 0) and (operator_dict[element] <= operator_dict[stack[-1]])): return True
elif stack[-1] == "(" or ((operator_assoc[element]==1) and (operator_dict[element] < operator_dict[stack[-1]])): return True
else: return False
def does_top_of_stack_have_operator():
return True if stack[-1] in operator_dict.keys() else False
def empty_stack():
while len(stack) != 0 :
temp = stack.pop()
output_queu.append(temp)
# main stream
for element in initial_expression:
operand_check(element)
parenthesis_check(element)
operator_check(element)
print("stack:",stack)
print("output queu",output_queu)
#sleep(0.5)
empty_stack()
print("stack:",stack)
print("output queu",output_queu)
尽管,它适用于 test2 "A*B+C-D":
stack: []
output queu ['A', 'B', '*', 'C', '+', 'D', '-']
对于 test3 "A-B*(C-D-E)/F-G":
stack: []
output queu ['A', 'B', 'C', 'D', '-', 'E', '-', '*', 'F', '/', '-', 'G', '-']
我真的很想完成这项工作,但我不知道如何进行,我有点卡住了。谁能帮我一把?
我还添加了我使用的伪代码:
Get next token t from the input queue
if t is an operand then
Add t to the output queue
if t is an operator then
while There is an operator τ at the top of the stack, and either t is leftassociative
and its precedence is less than or equal to the precedence of τ ,
or t is right-associative and its precedence is less than the precedence of τ do
Pop τ from the stack, to the output queue.
Push t on the stack.
if t is a left parenthesis then
Push t on the stack.
if t is a right parenthesis then
Pop the operators from the stack, to the output queue until the top of the stack
is a left parenthesis.
Pop the left parenthesis.
if No more tokens to get then
Pop the operators on the stack, if any, to the output queue.
注意:我知道我的代码现在有点乱,但我会在解决问题后处理它。
栈上有两个括号。哪个正在被删除?哪些应该删除?
elif element == ")":
while stack[-1] != "(":
temp = stack.pop()
output_queu.append(temp)
# to remove left parenthesis
stack.remove(stack[-1]) # <----
伪代码(强调)
如果t
是右括号则
- 从栈中弹出运算符,到输出队列,直到栈顶是左括号。
- 弹出左括号.
Docs.python.org(强调)
array.remove(x)
Remove the first occurrence of x from the array.
我正在尝试将 Dijkstra 的调车场算法 实施到 python,因为这将是一个很好的练习。但是,即使我的代码对于某些测试用例也能正常工作。其中一些无法正常工作。
在我的具体情况下,在我在图片中显示的位置之后无法正常工作:screenshot
这是我的代码:
operator_dict = {"^": 3,
"*": 2,
"/": 2,
"+": 1,
"-": 1,
#"(": 0,
#")": 8
}
parenthesis_dict = {
"(":1,
")":0
}
operator_assoc = {"^": 1, # right
"*": 0, # left
"/": 0,
"+": 0,
"-": 0,
"(": 0,
")": 0,
}
test1 = "A-B^C^D*(E-(F-G-H))/K"
test2 = "A*B+C-D"
test3 = "A-B*(C-D-E)/F-G"
from time import sleep
initial_expression = test1
stack = []
output_queu = []
# if it is an operand we push it to the output queu
def operand_check(element):
if (element not in operator_dict.keys()) and (element not in parenthesis_dict.keys()):
output_queu.append(element)
def parenthesis_check(element):
# push down the left parenthesis
if element == "(":
stack.append(element)
# if it's right parenthesis then pop everything out of stack until
# you reach left parenthesis
elif element == ")":
while stack[-1] != "(":
temp = stack.pop()
output_queu.append(temp)
# to remove left parenthesis
stack.remove(stack[-1])
def operator_check(element):
if element in operator_dict.keys():
while (len(stack) != 0) and assoc_precedence_check(element) and does_top_of_stack_have_operator():
temp = stack.pop()
output_queu.append(temp)
stack.append(element)
def assoc_precedence_check(element):
if stack[-1] == "(" or ((operator_assoc[element] == 0) and (operator_dict[element] <= operator_dict[stack[-1]])): return True
elif stack[-1] == "(" or ((operator_assoc[element]==1) and (operator_dict[element] < operator_dict[stack[-1]])): return True
else: return False
def does_top_of_stack_have_operator():
return True if stack[-1] in operator_dict.keys() else False
def empty_stack():
while len(stack) != 0 :
temp = stack.pop()
output_queu.append(temp)
# main stream
for element in initial_expression:
operand_check(element)
parenthesis_check(element)
operator_check(element)
print("stack:",stack)
print("output queu",output_queu)
#sleep(0.5)
empty_stack()
print("stack:",stack)
print("output queu",output_queu)
尽管,它适用于 test2 "A*B+C-D":
stack: []
output queu ['A', 'B', '*', 'C', '+', 'D', '-']
对于 test3 "A-B*(C-D-E)/F-G":
stack: []
output queu ['A', 'B', 'C', 'D', '-', 'E', '-', '*', 'F', '/', '-', 'G', '-']
我真的很想完成这项工作,但我不知道如何进行,我有点卡住了。谁能帮我一把?
我还添加了我使用的伪代码:
Get next token t from the input queue
if t is an operand then
Add t to the output queue
if t is an operator then
while There is an operator τ at the top of the stack, and either t is leftassociative
and its precedence is less than or equal to the precedence of τ ,
or t is right-associative and its precedence is less than the precedence of τ do
Pop τ from the stack, to the output queue.
Push t on the stack.
if t is a left parenthesis then
Push t on the stack.
if t is a right parenthesis then
Pop the operators from the stack, to the output queue until the top of the stack
is a left parenthesis.
Pop the left parenthesis.
if No more tokens to get then
Pop the operators on the stack, if any, to the output queue.
注意:我知道我的代码现在有点乱,但我会在解决问题后处理它。
栈上有两个括号。哪个正在被删除?哪些应该删除?
elif element == ")":
while stack[-1] != "(":
temp = stack.pop()
output_queu.append(temp)
# to remove left parenthesis
stack.remove(stack[-1]) # <----
伪代码(强调)
如果t
是右括号则
- 从栈中弹出运算符,到输出队列,直到栈顶是左括号。
- 弹出左括号.
Docs.python.org(强调)
array.remove(x)
Remove the first occurrence of x from the array.