From 17e1a92f499bb3d4f8ccabe084934f76d048a92a Mon Sep 17 00:00:00 2001 From: Chris McLennon Date: Thu, 5 Oct 2017 22:24:02 -0500 Subject: [PATCH] Refactor Stack --- .../Stacks/Balanced_Parentheses.py | 27 -------- .../Stacks/Infix_To_Postfix_Conversion.py | 48 ------------- data_structures/Stacks/Stack.py | 50 -------------- .../Stacks/balanced_parentheses.py | 21 ++++++ .../Stacks/infix_to_postfix_conversion.py | 62 +++++++++++++++++ data_structures/Stacks/stack.py | 68 +++++++++++++++++++ 6 files changed, 151 insertions(+), 125 deletions(-) delete mode 100644 data_structures/Stacks/Balanced_Parentheses.py delete mode 100644 data_structures/Stacks/Infix_To_Postfix_Conversion.py delete mode 100644 data_structures/Stacks/Stack.py create mode 100644 data_structures/Stacks/balanced_parentheses.py create mode 100644 data_structures/Stacks/infix_to_postfix_conversion.py create mode 100644 data_structures/Stacks/stack.py diff --git a/data_structures/Stacks/Balanced_Parentheses.py b/data_structures/Stacks/Balanced_Parentheses.py deleted file mode 100644 index 6b7740380..000000000 --- a/data_structures/Stacks/Balanced_Parentheses.py +++ /dev/null @@ -1,27 +0,0 @@ -# Author: OMKAR PATHAK - -import Stack - -def parseParenthesis(string): - balanced = 1 - index = 0 - myStack = Stack.Stack(len(string)) - while (index < len(string)) and (balanced == 1): - check = string[index] - if check == '(': - myStack.push(check) - else: - if myStack.isEmpty(): - balanced = 0 - else: - myStack.pop() - index += 1 - - if balanced == 1 and myStack.isEmpty(): - return True - else: - return False - -if __name__ == '__main__': - print(parseParenthesis('((()))')) # True - print(parseParenthesis('((())')) # False diff --git a/data_structures/Stacks/Infix_To_Postfix_Conversion.py b/data_structures/Stacks/Infix_To_Postfix_Conversion.py deleted file mode 100644 index e33926a3d..000000000 --- a/data_structures/Stacks/Infix_To_Postfix_Conversion.py +++ /dev/null @@ -1,48 +0,0 @@ -# Author: OMKAR PATHAK - -import Stack - -def isOperand(char): - return (ord(char) >= ord('a') and ord(char) <= ord('z')) or (ord(char) >= ord('A') and ord(char) <= ord('Z')) - -def precedence(char): - if char == '+' or char == '-': - return 1 - elif char == '*' or char == '/': - return 2 - elif char == '^': - return 3 - else: - return -1 - -def infixToPostfix(myExp, myStack): - postFix = [] - for i in range(len(myExp)): - if (isOperand(myExp[i])): - postFix.append(myExp[i]) - elif(myExp[i] == '('): - myStack.push(myExp[i]) - elif(myExp[i] == ')'): - topOperator = myStack.pop() - while(not myStack.isEmpty() and topOperator != '('): - postFix.append(topOperator) - topOperator = myStack.pop() - else: - while (not myStack.isEmpty()) and (precedence(myExp[i]) <= precedence(myStack.peek())): - postFix.append(myStack.pop()) - myStack.push(myExp[i]) - - while(not myStack.isEmpty()): - postFix.append(myStack.pop()) - return ' '.join(postFix) - -if __name__ == '__main__': - myExp = 'a+b*(c^d-e)^(f+g*h)-i' - myExp = [i for i in myExp] - print('Infix:',' '.join(myExp)) - myStack = Stack.Stack(len(myExp)) - print('Postfix:',infixToPostfix(myExp, myStack)) - - # OUTPUT: - # Infix: a + b * ( c ^ d - e ) ^ ( f + g * h ) - i - # Postfix: a b c d ^ e - f g h * + ^ * + i - diff --git a/data_structures/Stacks/Stack.py b/data_structures/Stacks/Stack.py deleted file mode 100644 index 41bbdc9d2..000000000 --- a/data_structures/Stacks/Stack.py +++ /dev/null @@ -1,50 +0,0 @@ -# Author: OMKAR PATHAK - -class Stack(object): - def __init__(self, limit = 10): - self.stack = [] - self.limit = limit - - # for printing the stack contents - def __str__(self): - return ' '.join([str(i) for i in self.stack]) - - # for pushing an element on to the stack - def push(self, data): - if len(self.stack) >= self.limit: - print('Stack Overflow') - else: - self.stack.append(data) - - # for popping the uppermost element - def pop(self): - if len(self.stack) <= 0: - return -1 - else: - return self.stack.pop() - - # for peeking the top-most element of the stack - def peek(self): - if len(self.stack) <= 0: - return -1 - else: - return self.stack[len(self.stack) - 1] - - # to check if stack is empty - def isEmpty(self): - return self.stack == [] - - # for checking the size of stack - def size(self): - return len(self.stack) - -if __name__ == '__main__': - myStack = Stack() - for i in range(10): - myStack.push(i) - print(myStack) - myStack.pop() # popping the top element - print(myStack) - myStack.peek() # printing the top element - myStack.isEmpty() - myStack.size() diff --git a/data_structures/Stacks/balanced_parentheses.py b/data_structures/Stacks/balanced_parentheses.py new file mode 100644 index 000000000..1c9a84843 --- /dev/null +++ b/data_structures/Stacks/balanced_parentheses.py @@ -0,0 +1,21 @@ +from Stack import Stack + +__author__ = 'Omkar Pathak' + + +def balanced_parentheses(parentheses): + """ Use a stack to check if a string of parentheses are balanced.""" + stack = Stack(len(parentheses)) + for parenthesis in parentheses: + if parenthesis == '(': + stack.push(parenthesis) + elif parenthesis == ')': + stack.pop() + return not stack.is_empty() + + +if __name__ == '__main__': + examples = ['((()))', '((())'] + print('Balanced parentheses demonstration:\n') + for example in examples: + print(example + ': ' + str(balanced_parentheses(example))) diff --git a/data_structures/Stacks/infix_to_postfix_conversion.py b/data_structures/Stacks/infix_to_postfix_conversion.py new file mode 100644 index 000000000..f0a8fd072 --- /dev/null +++ b/data_structures/Stacks/infix_to_postfix_conversion.py @@ -0,0 +1,62 @@ +import string + +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 + order of operation. + + https://en.wikipedia.org/wiki/Order_of_operations + """ + dictionary = {'+': 1, '-': 1, + '*': 2, '/': 2, + '^': 3} + return dictionary.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 + """ + stack = Stack(len(expression)) + postfix = [] + for char in expression: + if is_operand(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 == '(': + 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() + while not stack.is_empty(): + postfix.append(stack.pop()) + return ' '.join(postfix) + + +if __name__ == '__main__': + expression = 'a+b*(c^d-e)^(f+g*h)-i' + + print('Infix to Postfix Notation demonstration:\n') + print('Infix notation: ' + expression) + print('Postfix notation: ' + infix_to_postfix(expression)) diff --git a/data_structures/Stacks/stack.py b/data_structures/Stacks/stack.py new file mode 100644 index 000000000..0b100abf3 --- /dev/null +++ b/data_structures/Stacks/stack.py @@ -0,0 +1,68 @@ +__author__ = 'Omkar Pathak' + + +class Stack(object): + """ A stack is an abstract data type that serves as a collection of + elements with two principal operations: push() and pop(). push() adds an + element to the top of the stack, and pop() removes an element from the top + of a stack. The order in which elements come off of a stack are + Last In, First Out (LIFO). + + https://en.wikipedia.org/wiki/Stack_(abstract_data_type) + """ + + def __init__(self, limit=10): + self.stack = [] + self.limit = limit + + def __bool__(self): + return not bool(self.stack) + + def __str__(self): + return str(self.stack) + + def push(self, data): + """ Push an element to the top of the stack.""" + if len(self.stack) >= self.limit: + raise StackOverflowError + self.stack.append(data) + + def pop(self): + """ Pop an element off of the top of the stack.""" + if self.stack: + return self.stack.pop() + else: + raise IndexError('pop from an empty stack') + + def peek(self): + """ Peek at the top-most element of the stack.""" + if self.stack: + return self.stack[-1] + + def is_empty(self): + """ Check if a stack is empty.""" + return not bool(self.stack) + + def size(self): + """ Return the size of the stack.""" + return len(self.stack) + + +class StackOverflowError(BaseException): + pass + + +if __name__ == '__main__': + stack = Stack() + for i in range(10): + stack.push(i) + + print('Stack demonstration:\n') + print('Initial stack: ' + str(stack)) + print('pop(): ' + str(stack.pop())) + print('After pop(), the stack is now: ' + str(stack)) + print('peek(): ' + str(stack.peek())) + stack.push(100) + print('After push(100), the stack is now: ' + str(stack)) + print('is_empty(): ' + str(stack.is_empty())) + print('size(): ' + str(stack.size()))