mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-18 01:00:15 +00:00
Update infix to postfix (#3817)
* add test to infix_to_postfix_conversion * fixed pre-commit error * fixed build error * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
d8f573c0fb
commit
786b32431c
|
@ -674,6 +674,8 @@
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_056/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_056/sol1.py)
|
||||||
* Problem 057
|
* Problem 057
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_057/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_057/sol1.py)
|
||||||
|
* Problem 058
|
||||||
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_058/sol1.py)
|
||||||
* Problem 062
|
* Problem 062
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py)
|
||||||
* Problem 063
|
* Problem 063
|
||||||
|
@ -699,6 +701,8 @@
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_080/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_080/sol1.py)
|
||||||
* Problem 081
|
* Problem 081
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_081/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_081/sol1.py)
|
||||||
|
* Problem 087
|
||||||
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_087/sol1.py)
|
||||||
* Problem 091
|
* Problem 091
|
||||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_091/sol1.py)
|
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_091/sol1.py)
|
||||||
* Problem 097
|
* Problem 097
|
||||||
|
@ -817,6 +821,7 @@
|
||||||
* [Prefix Function](https://github.com/TheAlgorithms/Python/blob/master/strings/prefix_function.py)
|
* [Prefix Function](https://github.com/TheAlgorithms/Python/blob/master/strings/prefix_function.py)
|
||||||
* [Rabin Karp](https://github.com/TheAlgorithms/Python/blob/master/strings/rabin_karp.py)
|
* [Rabin Karp](https://github.com/TheAlgorithms/Python/blob/master/strings/rabin_karp.py)
|
||||||
* [Remove Duplicate](https://github.com/TheAlgorithms/Python/blob/master/strings/remove_duplicate.py)
|
* [Remove Duplicate](https://github.com/TheAlgorithms/Python/blob/master/strings/remove_duplicate.py)
|
||||||
|
* [Reverse Letters](https://github.com/TheAlgorithms/Python/blob/master/strings/reverse_letters.py)
|
||||||
* [Reverse Words](https://github.com/TheAlgorithms/Python/blob/master/strings/reverse_words.py)
|
* [Reverse Words](https://github.com/TheAlgorithms/Python/blob/master/strings/reverse_words.py)
|
||||||
* [Split](https://github.com/TheAlgorithms/Python/blob/master/strings/split.py)
|
* [Split](https://github.com/TheAlgorithms/Python/blob/master/strings/split.py)
|
||||||
* [Swap Case](https://github.com/TheAlgorithms/Python/blob/master/strings/swap_case.py)
|
* [Swap Case](https://github.com/TheAlgorithms/Python/blob/master/strings/swap_case.py)
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
class Stack:
|
|
||||||
def __init__(self):
|
|
||||||
self.stack = []
|
|
||||||
self.top = 0
|
|
||||||
|
|
||||||
def is_empty(self):
|
|
||||||
return self.top == 0
|
|
||||||
|
|
||||||
def push(self, item):
|
|
||||||
if self.top < len(self.stack):
|
|
||||||
self.stack[self.top] = item
|
|
||||||
else:
|
|
||||||
self.stack.append(item)
|
|
||||||
|
|
||||||
self.top += 1
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
if self.is_empty():
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
self.top -= 1
|
|
||||||
return self.stack[self.top]
|
|
|
@ -1,57 +1,67 @@
|
||||||
import string
|
"""
|
||||||
|
https://en.wikipedia.org/wiki/Infix_notation
|
||||||
|
https://en.wikipedia.org/wiki/Reverse_Polish_notation
|
||||||
|
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .balanced_parentheses import balanced_parentheses
|
||||||
from .stack import Stack
|
from .stack import Stack
|
||||||
|
|
||||||
__author__ = "Omkar Pathak"
|
|
||||||
|
|
||||||
|
def precedence(char: str) -> int:
|
||||||
def is_operand(char):
|
"""
|
||||||
return char in string.ascii_letters or char in string.digits
|
Return integer value representing an operator's precedence, or
|
||||||
|
|
||||||
|
|
||||||
def precedence(char):
|
|
||||||
"""Return integer value representing an operator's precedence, or
|
|
||||||
order of operation.
|
order of operation.
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/Order_of_operations
|
https://en.wikipedia.org/wiki/Order_of_operations
|
||||||
"""
|
"""
|
||||||
dictionary = {"+": 1, "-": 1, "*": 2, "/": 2, "^": 3}
|
return {"+": 1, "-": 1, "*": 2, "/": 2, "^": 3}.get(char, -1)
|
||||||
return dictionary.get(char, -1)
|
|
||||||
|
|
||||||
|
|
||||||
def infix_to_postfix(expression):
|
def infix_to_postfix(expression_str: str) -> str:
|
||||||
"""Convert infix notation to postfix notation using the Shunting-yard
|
|
||||||
algorithm.
|
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
|
||||||
https://en.wikipedia.org/wiki/Infix_notation
|
|
||||||
https://en.wikipedia.org/wiki/Reverse_Polish_notation
|
|
||||||
"""
|
"""
|
||||||
stack = Stack(len(expression))
|
>>> infix_to_postfix("(1*(2+3)+4))")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValueError: Mismatched parentheses
|
||||||
|
>>> infix_to_postfix("")
|
||||||
|
''
|
||||||
|
>>> infix_to_postfix("3+2")
|
||||||
|
'3 2 +'
|
||||||
|
>>> infix_to_postfix("(3+4)*5-6")
|
||||||
|
'3 4 + 5 * 6 -'
|
||||||
|
>>> infix_to_postfix("(1+2)*3/4-5")
|
||||||
|
'1 2 + 3 * 4 / 5 -'
|
||||||
|
>>> infix_to_postfix("a+b*c+(d*e+f)*g")
|
||||||
|
'a b c * + d e * f + g * +'
|
||||||
|
>>> infix_to_postfix("x^y/(5*z)+2")
|
||||||
|
'x y ^ 5 z * / 2 +'
|
||||||
|
"""
|
||||||
|
if not balanced_parentheses(expression_str):
|
||||||
|
raise ValueError("Mismatched parentheses")
|
||||||
|
stack = Stack()
|
||||||
postfix = []
|
postfix = []
|
||||||
for char in expression:
|
for char in expression_str:
|
||||||
if is_operand(char):
|
if char.isalpha() or char.isdigit():
|
||||||
postfix.append(char)
|
postfix.append(char)
|
||||||
elif char not in {"(", ")"}:
|
|
||||||
while not stack.is_empty() and precedence(char) <= precedence(stack.peek()):
|
|
||||||
postfix.append(stack.pop())
|
|
||||||
stack.push(char)
|
|
||||||
elif char == "(":
|
elif char == "(":
|
||||||
stack.push(char)
|
stack.push(char)
|
||||||
elif char == ")":
|
elif char == ")":
|
||||||
while not stack.is_empty() and stack.peek() != "(":
|
while not stack.is_empty() and stack.peek() != "(":
|
||||||
postfix.append(stack.pop())
|
postfix.append(stack.pop())
|
||||||
# Pop '(' from stack. If there is no '(', there is a mismatched
|
|
||||||
# parentheses.
|
|
||||||
if stack.peek() != "(":
|
|
||||||
raise ValueError("Mismatched parentheses")
|
|
||||||
stack.pop()
|
stack.pop()
|
||||||
|
else:
|
||||||
|
while not stack.is_empty() and precedence(char) <= precedence(stack.peek()):
|
||||||
|
postfix.append(stack.pop())
|
||||||
|
stack.push(char)
|
||||||
while not stack.is_empty():
|
while not stack.is_empty():
|
||||||
postfix.append(stack.pop())
|
postfix.append(stack.pop())
|
||||||
return " ".join(postfix)
|
return " ".join(postfix)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
from doctest import testmod
|
||||||
|
|
||||||
|
testmod()
|
||||||
expression = "a+b*(c^d-e)^(f+g*h)-i"
|
expression = "a+b*(c^d-e)^(f+g*h)-i"
|
||||||
|
|
||||||
print("Infix to Postfix Notation demonstration:\n")
|
print("Infix to Postfix Notation demonstration:\n")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user