Skip to content

Update infix to postfix #3817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,8 @@
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_056/sol1.py)
* Problem 057
* [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
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py)
* Problem 063
Expand All @@ -699,6 +701,8 @@
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_080/sol1.py)
* Problem 081
* [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
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_091/sol1.py)
* Problem 097
Expand Down Expand Up @@ -817,6 +821,7 @@
* [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)
* [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)
* [Split](https://github.com/TheAlgorithms/Python/blob/master/strings/split.py)
* [Swap Case](https://github.com/TheAlgorithms/Python/blob/master/strings/swap_case.py)
Expand Down
22 changes: 0 additions & 22 deletions data_structures/stacks/__init__.py
Original file line number Diff line number Diff line change
@@ -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]
70 changes: 40 additions & 30 deletions data_structures/stacks/infix_to_postfix_conversion.py
Original file line number Diff line number Diff line change
@@ -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

__author__ = "Omkar Pathak"


def is_operand(char):
return char in string.ascii_letters or char in string.digits


def precedence(char):
"""Return integer value representing an operator's precedence, or
def precedence(char: str) -> int:
"""
Return integer value representing an operator's precedence, or
order of operation.

https://en.wikipedia.org/wiki/Order_of_operations
"""
dictionary = {"+": 1, "-": 1, "*": 2, "/": 2, "^": 3}
return dictionary.get(char, -1)

return {"+": 1, "-": 1, "*": 2, "/": 2, "^": 3}.get(char, -1)

def infix_to_postfix(expression):
"""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
def infix_to_postfix(expression_str: str) -> str:
"""
>>> 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 +'
"""
stack = Stack(len(expression))
if not balanced_parentheses(expression_str):
raise ValueError("Mismatched parentheses")
stack = Stack()
postfix = []
for char in expression:
if is_operand(char):
for char in expression_str:
if char.isalpha() or char.isdigit():
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 == "(":
stack.push(char)
elif char == ")":
while not stack.is_empty() and stack.peek() != "(":
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()
else:
while not stack.is_empty() and precedence(char) <= precedence(stack.peek()):
postfix.append(stack.pop())
stack.push(char)
while not stack.is_empty():
postfix.append(stack.pop())
return " ".join(postfix)


if __name__ == "__main__":
from doctest import testmod

testmod()
expression = "a+b*(c^d-e)^(f+g*h)-i"

print("Infix to Postfix Notation demonstration:\n")
Expand Down