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
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.
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
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)
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.
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)