Implement A Queue using Two Stacks Python - python

I've been going over some of the many coding interview questions. I was wondering how you would go about implementing a queue using two stacks in Python? Python is not my strongest language so I need all the help I can get.
Like the enqueue, dequeue, and front functions.

class Queue(object):
def __init__(self):
self.instack=[]
self.outstack=[]
def enqueue(self,element):
self.instack.append(element)
def dequeue(self):
if not self.outstack:
while self.instack:
self.outstack.append(self.instack.pop())
return self.outstack.pop()
q=Queue()
for i in range(10):
q.enqueue(i)
for i in xrange(10):
print q.dequeue(),

class MyQueue(object):
def __init__(self):
self.first = []
self.second = []
def peek(self):
if not self.second:
while self.first:
self.second.append(self.first.pop());
return self.second[len(self.second)-1];
def pop(self):
if not self.second:
while self.first:
self.second.append(self.first.pop());
return self.second.pop();
def put(self, value):
self.first.append(value);
queue = MyQueue()
t = int(raw_input())
for line in xrange(t):
values = map(int, raw_input().split())
if values[0] == 1:
queue.put(values[1])
elif values[0] == 2:
queue.pop()
else:
print queue.peek()

class Stack:
def __init__(self):
self.elements = []
def push(self, item):
self.elements.append(item)
def pop(self):
return self.elements.pop()
def size(self):
return len(self.elements)
def is_empty(self):
return self.size() == 0
class CreatingQueueWithTwoStacks:
def __init__(self):
self.stack_1 = Stack()
self.stack_2 = Stack()
def enqueue(self, item):
self.stack_1.push(item)
def dequeue(self):
if not self.stack_1.is_empty():
while self.stack_1.size() > 0:
self.stack_2.push(self.stack_1.pop())
res = self.stack_2.pop()
while self.stack_2.size() > 0:
self.stack_1.push(self.stack_2.pop())
return res
if __name__ == '__main__':
q = CreatingQueueWithTwoStacks()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
a = q.dequeue()
print(a)
b = q.dequeue()
print(b)
c = q.dequeue()
print(c)
d = q.dequeue()
print(d)
q.enqueue(5)
q.enqueue(6)
print(q.dequeue())

First, create a stack object. Then create a queue out of 2 stacks. Since a Stack = FIFO (first in first out), and Queue = LIFO (last in first out), add all the items to the "in stack" and then pop them into the output.
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def is_empty(self):
return self.items == []
class Queue2Stacks(object):
def __init__(self):
# Two Stacks
self.in_stack = Stack()
self.out_stack = Stack()
def enqueue(self, item):
self.in_stack.push(item)
def dequeue(self):
if self.out_stack.is_empty:
while self.in_stack.size()>0:
self.out_stack.push(self.in_stack.pop())
return self.out_stack.items.pop()
#driver code
q = Queue2Stacks()
for i in range(5):
q.enqueue(i)
for i in range(5):
print(q.dequeue(i))
Gives you 0,1,2,3,4

Stack1, Stack2.
Enqueue:
Push el into stack1.
Dequeue:
While (!empty(Stack1))
el = Pop from stack1
Push el into stack2
returnEl = Pop from Stack2
While (!empty(Stack2))
el = Pop from stack2
Push el into stack1
return returnEl
That is a way of implementing the algorithm in pseudocode, it shouldn`t be difficult to implement it in python knowing the basic syntax.

I found this solution that works for implementing a queue using two stacks. I use set instead of queue. We can use the following implementation. for the time cost of m function calls on your queue. This optimization can be any mix of enqueue and dequeue calls.
#
#
class Stack():
def __init__(self):
self.stk = []
def pop(self):
"""raises IndexError if you pop when it's empty"""
return self.stk.pop()
def push(self, elt):
self.stk.append(elt)
def is_empty(self):
return len(self.stk) == 0
def peek(self):
if not self.stk.is_empty():
return self.stk[-1]
class Queue():
def __init__(self):
self.q = Stack() # the primary queue
self.b = Stack() # the reverse, opposite q (a joke: q vs b)
self.front = None
def is_empty(self):
return self.q.is_empty()
def peek(self):
if self.q.is_empty():
return None
else:
return self.front
def enqueue(self, elt):
self.front = elt
self.q.push(elt)
def dequeue(self):
"""raises IndexError if you dequeue from an empty queue"""
while not self.q.is_empty() > 0:
elt = self.q.pop()
self.b.push(elt)
val = self.b.pop()
elt = None
while not self.b.is_empty() > 0:
elt = self.b.pop()
self.q.push(elt)
self.front = elt
return val
# Now let's test
class TestQueueTwoStacks(unittest.TestCase):
def setUp(self):
self.q = Queue()
def test_queuedequue(self):
"""queue up 5 integers, check they are in there, dequeue them, check for emptiness, perform other blackbox and whitebox tests"""
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l = range(5)
for i in l:
self.q.enqueue(i)
self.assertEqual(4, self.q.peek())
self.assertEqual(l, self.q.q.stk)
s = []
l.reverse()
for i in l:
elt = self.q.dequeue()
s.append(elt)
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l.reverse()
self.assertEqual(s, l)
self.assertEqual([], self.q.b.stk)
self.assertEqual([], self.q.q.stk)
if __name__ == "__main__":
# unittest.main()
suite = unittest.TestLoader().loadTestsFromTestCase(TestQueueTwoStacks)
unittest.TextTestRunner(verbosity=2).run(suite)

Related

How do I get a mirrored queue using stack?

I have defined the Stack and Queue class already so I can use any of the Queue methods - Queue(), enqueue(), dequeue(), peek(), size() and is_empty() and any of the Stack ADT methods: Stack(), push(), pop(), peek(), size() and is_empty().
What I basically need to do is modify the parameter Queue object so that the original queue items appear in their original order followed by a copy of the queue items in reverse order.
Here is what I have so far. But this is only giving me the reversed queue. Can someone help how I can modify the queue to both the original and reversed versions.
The Stack class:
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
if Stack.is_empty(self) == True:
return None
else:
return self.items.pop()
def peek(self):
if Stack.is_empty(self) == True:
return None
else:
return self.items[-1]
def size(self):
return len(self.items)
Queue class:
class Queue:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
if len(self.items)==0:
raise IndexError("ERROR: The queue is empty!")
return self.items.pop()
def size(self):
return len(self.items)
def peek(self):
if Queue.is_empty(self) == True:
raise IndexError("ERROR: The queue is empty!")
else:
return self.items[-1]
def __eq__(self, other):
self.other = other
if self.items == self.other:
return True
else:
return False
def clear(self):
del self.items[:]
def __str__(self):
return "{}".format(self.items[::-1])
Function I am required to define:
def mirror_queue(q):
stack = Stack()
while not q.is_empty():
stack.push(q.dequeue())
while not stack.is_empty():
q.enqueue(stack.pop())
---test
q1 = Queue()
q1.enqueue(1)
q1.enqueue(2)
q1.enqueue(3)
print(q1)
mirror_queue(q1)
print(q1)
---Expected Output
Queue: [1, 2, 3]
Queue: [1, 2, 3, 3, 2, 1]
---Gotten Ouput
Queue: [1, 2, 3]
Queue: [3, 2, 1]
mirror_queue seems to just reverse your queue.
My approach:
Don’t change the original q but reverse a copy of q1 called q1r.
Afterwards concat those two which then is your result (q1 + q1r).
When you use the function dequeue, it takes out one item from your queue, so when the first loop ends you have an empty queue and the stack with 3 elements. When you pop from your stack it enqueue back to your queue in reverse order.
You should make a copy of the elements of the queue without dequeue it in order to archive what you want.

Iterative Towers of Hanoi using queue but the reverse function says it is not defined

class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return "Node({})".format(self.value)
__repr__ = __str__
class Queue:
def __init__(self):
#Constructor take head and tail
self.head=None
self.tail=None
def __str__(self):
#proper format
temp=self.head
out=[]
while temp:
out.append(str(temp.value))
temp=temp.next
out=' '.join(out)
return ('Head:{}\nTail:{}\nQueue:{}'.format(self.head,self.tail,out))
__repr__=__str__
def isEmpty(self):
#check if the queue is empty
return (self.head == None)
def len(self):
#check the length of queue
current = self.head
len = 0
while current != None:
len += 1
current = current.next
return len
def enqueue(self, value):
#add a node to the end of queue
node = Node(value)
if self.isEmpty():
self.head = node
self.tail = node
else:
self.tail.next = node
self.tail = node
def dequeue(self):
#delete a node from the beginning of queue
if self.isEmpty():
return 'Queue is empty'
elif (self.head == self.tail):
pop = self.head.value
self.head = None
self.tail = None
return pop
else:
popped = self.head.value
self.head = self.head.next
return popped
def peek(self):
#show the first node
return self.head.value
class QueueTower:
def __init__(self, numDisks, A=Queue(), B=Queue(), C= Queue()):
self.numDisks = numDisks
self.A = Queue()
self.B = Queue()
self.C = Queue()
for i in (numDisks, 0, -1):
self.A.enqueue(i)
def reversequeue(q):
#reverse the queue without using stack
if q.isEmpty() == False:
data = q.peek()
q.dequeue()
q = reversequeue(q) #recurssion
q.enqueue(data)
return q
return Queue()
def validMove(self, a, b):
if not a.len():
c = reversequeue(b)
a.enqueue(c.dequeue())
elif not b.len():
d = reversequeue(a)
b.enqueue(d.dequeue())
elif int(a.peek()) > int(b.peek()):
e = reversequeue(b)
a.enqueue(e.dequeue())
else:
f = reversequeue(a)
b.enqueue(f.dequeue())
def hanoi(self, n):
if n%2 == 0:
self.B, self.C = self.C, self.B
move = 2**n
for i in range(1, move):
if i%3==1:
self.validMove(self.A, self.C)
if i%3==2:
self.validMove(self.A, self.B)
if i%3==0:
self.validMove(self.B, self.C)
print("rod " + str(self.A)+ " has " + str(self.A.len()), "rod B " + str(self.B.len()), "rod C "+ str(self.C.len()))
print("move needed is " + str(move-1))
tower1 = QueueTower(3)
tower1.hanoi(3)
I have tested to code for function reversequeue. It works fine for other example but I can't make it work for this. It returns that reversequeue is undefined. I put the function inside the class. Please help me understand the problem.
Should I put the function in class Queue. What should I do in this situation?
Thank you so much for helping.
You forgot your self:
class QueueTower:
def __init__(self, numDisks, A=Queue(), B=Queue(), C= Queue()):
self.numDisks = numDisks
self.A = Queue()
self.B = Queue()
self.C = Queue()
for i in (numDisks, 0, -1):
self.A.enqueue(i)
def reversequeue(self, q):
#reverse the queue without using stack
if q.isEmpty() == False:
data = q.peek()
q.dequeue()
q = self.reversequeue(q) #recurssion
q.enqueue(data)
return q
return Queue()
def validMove(self, a, b):
if not a.len():
c = self.reversequeue(b)
a.enqueue(c.dequeue())
# code continues

Implement a queue with 2 stacks python and analyze the running time

I've been going over some of the many coding interview questions.
I was wondering about implementing a queue using two stacks in Python. I'm working on algorithm question to implement a queue with two stacks for purposes of understanding both data structures.
I have the below:
class QueueTwoStacks:
def __init__(self):
self.in_stack = []
self.out_stack = []
def enqueue(self, item):
self.in_stack.append(item)
def dequeue(self):
if len(self.out_stack) == 0:
# Move items from in_stack to out_stack, reversing order
while len(self.in_stack) > 0:
newest_in_stack_item = self.in_stack.pop()
self.out_stack.append(newest_in_stack_item)
# If out_stack is still empty, raise an error
if len(self.out_stack) == 0:
raise IndexError("Can't dequeue from empty queue!")
return self.out_stack.pop()
What is the runtime analysis for this one?
Why is it true that we can get O(m)O(m) runtime for mm function calls.
Am I assuming have a stack implementation and it gives O(1)O(1) time push and pop?
I appreciate your explanation for this. thank you.
Yes. We can Optimize for the time cost of m function calls on your queue. This optimization can be any mix of enqueue and dequeue calls.
Assume you already have a stack implementation and it gives O(1)O(1) time push and pop.
#
#
class Stack():
def __init__(self):
self.stk = []
def pop(self):
"""raises IndexError if you pop when it's empty"""
return self.stk.pop()
def push(self, elt):
self.stk.append(elt)
def is_empty(self):
return len(self.stk) == 0
def peek(self):
if not self.stk.is_empty():
return self.stk[-1]
class Queue():
def __init__(self):
self.q = Stack() # the primary queue
self.b = Stack() # the reverse, opposite q (a joke: q vs b)
self.front = None
def is_empty(self):
return self.q.is_empty()
def peek(self):
if self.q.is_empty():
return None
else:
return self.front
def enqueue(self, elt):
self.front = elt
self.q.push(elt)
def dequeue(self):
"""raises IndexError if you dequeue from an empty queue"""
while not self.q.is_empty() > 0:
elt = self.q.pop()
self.b.push(elt)
val = self.b.pop()
elt = None
while not self.b.is_empty() > 0:
elt = self.b.pop()
self.q.push(elt)
self.front = elt
return val
# Now let's test
class TestQueueTwoStacks(unittest.TestCase):
def setUp(self):
self.q = Queue()
def test_queuedequue(self):
"""queue up 5 integers, check they are in there, dequeue them, check for emptiness, perform other blackbox and whitebox tests"""
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l = range(5)
for i in l:
self.q.enqueue(i)
self.assertEqual(4, self.q.peek())
self.assertEqual(l, self.q.q.stk)
s = []
l.reverse()
for i in l:
elt = self.q.dequeue()
s.append(elt)
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l.reverse()
self.assertEqual(s, l)
self.assertEqual([], self.q.b.stk)
self.assertEqual([], self.q.q.stk)
if __name__ == "__main__":
# unittest.main()
suite = unittest.TestLoader().loadTestsFromTestCase(TestQueueTwoStacks)
unittest.TextTestRunner(verbosity=2).run(suite)

How to convert NoneType to int in python?

I want to try to convert a decimal number to a binary number using stacks in Python but I got this error.
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
def divideBy2(decNumber):
remstack = Stack()
while decNumber > 0:
rem = decNumber % 2
remstack.push(rem)
decNumber = decNumber // 2
binString = ""
while not remstack.is_empty():
binString = binString + str(remstack.pop())
return binString
print(divideBy2(42))
Your pop method is missing a return.

Python Priority Queue checking to see if item exists without looping

import heapq
class PriorityQueue:
def __init__(self):
self.heap = []
def push(self, item, priority):
pair = (priority,item)
heapq.heappush(self.heap,pair)
def pop(self):
return heapq.heappop(self.heap)
def isEmpty(self):
return len(self.heap) == 0
def clear(self):
while not (self.isEmpty()):
self.heap.pop()
def getHeap(self):
return self.heap
def getLeng(self):
return len(self.heap)
def exists(self, item):
return len(list(set(self.heap) & set(item)))
pq = PriorityQueue()
x = "test"
pq.push(x,1)
print pq.exists(x)
it printed 0 when it should print 1 since intersection of a set with x and another set with x should be 1
am i overlooking things?
why is it printing 0 instead of 1?
You are pushing tuples of (priority,value) to the heap but want the exist method to work only on values, so you should get a value-only list/iterator out of your heap, something like this:
def exists(self, item):
return item in (x[1] for x in self.heap)

Categories

Resources