Skip to content

Commit 606e696

Browse files
authored
Merge pull request #146 from chrismclennon/stack
Refactor data_structures.Stacks
2 parents a093f55 + 17e1a92 commit 606e696

6 files changed

+151
-125
lines changed

Diff for: data_structures/Stacks/Balanced_Parentheses.py

-27
This file was deleted.

Diff for: data_structures/Stacks/Infix_To_Postfix_Conversion.py

-48
This file was deleted.

Diff for: data_structures/Stacks/Stack.py

-50
This file was deleted.

Diff for: data_structures/Stacks/balanced_parentheses.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from Stack import Stack
2+
3+
__author__ = 'Omkar Pathak'
4+
5+
6+
def balanced_parentheses(parentheses):
7+
""" Use a stack to check if a string of parentheses are balanced."""
8+
stack = Stack(len(parentheses))
9+
for parenthesis in parentheses:
10+
if parenthesis == '(':
11+
stack.push(parenthesis)
12+
elif parenthesis == ')':
13+
stack.pop()
14+
return not stack.is_empty()
15+
16+
17+
if __name__ == '__main__':
18+
examples = ['((()))', '((())']
19+
print('Balanced parentheses demonstration:\n')
20+
for example in examples:
21+
print(example + ': ' + str(balanced_parentheses(example)))
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import string
2+
3+
from Stack import Stack
4+
5+
__author__ = 'Omkar Pathak'
6+
7+
8+
def is_operand(char):
9+
return char in string.ascii_letters or char in string.digits
10+
11+
12+
def precedence(char):
13+
""" Return integer value representing an operator's precedence, or
14+
order of operation.
15+
16+
https://en.wikipedia.org/wiki/Order_of_operations
17+
"""
18+
dictionary = {'+': 1, '-': 1,
19+
'*': 2, '/': 2,
20+
'^': 3}
21+
return dictionary.get(char, -1)
22+
23+
24+
def infix_to_postfix(expression):
25+
""" Convert infix notation to postfix notation using the Shunting-yard
26+
algorithm.
27+
28+
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
29+
https://en.wikipedia.org/wiki/Infix_notation
30+
https://en.wikipedia.org/wiki/Reverse_Polish_notation
31+
"""
32+
stack = Stack(len(expression))
33+
postfix = []
34+
for char in expression:
35+
if is_operand(char):
36+
postfix.append(char)
37+
elif char not in {'(', ')'}:
38+
while (not stack.is_empty()
39+
and precedence(char) <= precedence(stack.peek())):
40+
postfix.append(stack.pop())
41+
stack.push(char)
42+
elif char == '(':
43+
stack.push(char)
44+
elif char == ')':
45+
while not stack.is_empty() and stack.peek() != '(':
46+
postfix.append(stack.pop())
47+
# Pop '(' from stack. If there is no '(', there is a mismatched
48+
# parentheses.
49+
if stack.peek() != '(':
50+
raise ValueError('Mismatched parentheses')
51+
stack.pop()
52+
while not stack.is_empty():
53+
postfix.append(stack.pop())
54+
return ' '.join(postfix)
55+
56+
57+
if __name__ == '__main__':
58+
expression = 'a+b*(c^d-e)^(f+g*h)-i'
59+
60+
print('Infix to Postfix Notation demonstration:\n')
61+
print('Infix notation: ' + expression)
62+
print('Postfix notation: ' + infix_to_postfix(expression))

Diff for: data_structures/Stacks/stack.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
__author__ = 'Omkar Pathak'
2+
3+
4+
class Stack(object):
5+
""" A stack is an abstract data type that serves as a collection of
6+
elements with two principal operations: push() and pop(). push() adds an
7+
element to the top of the stack, and pop() removes an element from the top
8+
of a stack. The order in which elements come off of a stack are
9+
Last In, First Out (LIFO).
10+
11+
https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
12+
"""
13+
14+
def __init__(self, limit=10):
15+
self.stack = []
16+
self.limit = limit
17+
18+
def __bool__(self):
19+
return not bool(self.stack)
20+
21+
def __str__(self):
22+
return str(self.stack)
23+
24+
def push(self, data):
25+
""" Push an element to the top of the stack."""
26+
if len(self.stack) >= self.limit:
27+
raise StackOverflowError
28+
self.stack.append(data)
29+
30+
def pop(self):
31+
""" Pop an element off of the top of the stack."""
32+
if self.stack:
33+
return self.stack.pop()
34+
else:
35+
raise IndexError('pop from an empty stack')
36+
37+
def peek(self):
38+
""" Peek at the top-most element of the stack."""
39+
if self.stack:
40+
return self.stack[-1]
41+
42+
def is_empty(self):
43+
""" Check if a stack is empty."""
44+
return not bool(self.stack)
45+
46+
def size(self):
47+
""" Return the size of the stack."""
48+
return len(self.stack)
49+
50+
51+
class StackOverflowError(BaseException):
52+
pass
53+
54+
55+
if __name__ == '__main__':
56+
stack = Stack()
57+
for i in range(10):
58+
stack.push(i)
59+
60+
print('Stack demonstration:\n')
61+
print('Initial stack: ' + str(stack))
62+
print('pop(): ' + str(stack.pop()))
63+
print('After pop(), the stack is now: ' + str(stack))
64+
print('peek(): ' + str(stack.peek()))
65+
stack.push(100)
66+
print('After push(100), the stack is now: ' + str(stack))
67+
print('is_empty(): ' + str(stack.is_empty()))
68+
print('size(): ' + str(stack.size()))

0 commit comments

Comments
 (0)