mirror of
https://hub.njuu.cf/TheAlgorithms/Python.git
synced 2023-10-11 13:06:12 +08:00
Created Dijkstra's Two Stack Algorithm (#2321)
* created dijkstra's two stack algorithm * Made changes to dijkstras two stack algorithm for documentation and testing purposes. * Made changes to dijkstras two stack algorithm for documentation and testing purposes. * Fixed Grammar Mistake * Added Explanation Reference * Imported stack instead of using my own Changed a few minor things. * Imported stack instead of using my own Changed a few minor things. * Update data_structures/stacks/dijkstras_two_stack_algorithm.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update dijkstras_two_stack_algorithm.py Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
parent
456893cb5f
commit
d3199da000
83
data_structures/stacks/dijkstras_two_stack_algorithm.py
Normal file
83
data_structures/stacks/dijkstras_two_stack_algorithm.py
Normal file
@ -0,0 +1,83 @@
|
||||
"""
|
||||
Author: Alexander Joslin
|
||||
GitHub: github.com/echoaj
|
||||
|
||||
Explanation: https://medium.com/@haleesammar/implemented-in-js-dijkstras-2-stack-
|
||||
algorithm-for-evaluating-mathematical-expressions-fc0837dae1ea
|
||||
|
||||
We can use Dijkstra's two stack algorithm to solve an equation
|
||||
such as: (5 + ((4 * 2) * (2 + 3)))
|
||||
|
||||
THESE ARE THE ALGORITHM'S RULES:
|
||||
RULE 1: Scan the expression from left to right. When an operand is encountered,
|
||||
push it onto the the operand stack.
|
||||
|
||||
RULE 2: When an operator is encountered in the expression,
|
||||
push it onto the operator stack.
|
||||
|
||||
RULE 3: When a left parenthesis is encountered in the expression, ignore it.
|
||||
|
||||
RULE 4: When a right parenthesis is encountered in the expression,
|
||||
pop an operator off the operator stack. The two operands it must
|
||||
operate on must be the last two operands pushed onto the operand stack.
|
||||
We therefore pop the operand stack twice, perform the operation,
|
||||
and push the result back onto the operand stack so it will be available
|
||||
for use as an operand of the next operator popped off the operator stack.
|
||||
|
||||
RULE 5: When the entire infix expression has been scanned, the value left on
|
||||
the operand stack represents the value of the expression.
|
||||
|
||||
NOTE: It only works with whole numbers.
|
||||
"""
|
||||
__author__ = "Alexander Joslin"
|
||||
|
||||
from .stack import Stack
|
||||
|
||||
import operator as op
|
||||
|
||||
|
||||
def dijkstras_two_stack_algorithm(equation: str) -> int:
|
||||
"""
|
||||
DocTests
|
||||
>>> dijkstras_two_stack_algorithm("(5 + 3)")
|
||||
8
|
||||
>>> dijkstras_two_stack_algorithm("((9 - (2 + 9)) + (8 - 1))")
|
||||
5
|
||||
>>> dijkstras_two_stack_algorithm("((((3 - 2) - (2 + 3)) + (2 - 4)) + 3)")
|
||||
-3
|
||||
|
||||
:param equation: a string
|
||||
:return: result: an integer
|
||||
"""
|
||||
operators = {"*": op.mul, "/": op.truediv, "+": op.add, "-": op.sub}
|
||||
|
||||
operand_stack = Stack()
|
||||
operator_stack = Stack()
|
||||
|
||||
for i in equation:
|
||||
if i.isdigit():
|
||||
# RULE 1
|
||||
operand_stack.push(int(i))
|
||||
elif i in operators:
|
||||
# RULE 2
|
||||
operator_stack.push(i)
|
||||
elif i == ")":
|
||||
# RULE 4
|
||||
opr = operator_stack.peek()
|
||||
operator_stack.pop()
|
||||
num1 = operand_stack.peek()
|
||||
operand_stack.pop()
|
||||
num2 = operand_stack.peek()
|
||||
operand_stack.pop()
|
||||
|
||||
total = operators[opr](num2, num1)
|
||||
operand_stack.push(total)
|
||||
|
||||
# RULE 5
|
||||
return operand_stack.peek()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
equation = "(5 + ((4 * 2) * (2 + 3)))"
|
||||
# answer = 45
|
||||
print(f"{equation} = {dijkstras_two_stack_algorithm(equation)}")
|
Loading…
Reference in New Issue
Block a user