This is a SetOfStacks problem (CTCI 3.3) implementation by myself in Python. Simply, I want to limit the size of the stack by, say 10. So, when I try to push more than the capacity, I generate one more stack to let the user keep pushing new elements. I tried to represent this into collections.defaultdict(list) data structure. To track the stack number in use, I made a variable named current_stack. However, even in the over-capacity case (please see the design at ##### mark), it seems the current_stack does not increase as intended. What's wrong with my code? Wouldn't the self.current_stack work kind of a global variable within the object?
class SetOfStacks():
def __init__(self, stacksize):
self.size = stacksize # const
self.c = collections.defaultdict(list)
self.current_stack = 0 # self.c[self.current_stack]
def push(self, e):
if len(c[self.current_stack]) + 1 > self.size: #####
self.current_stack += 1
self.c[self.current_stack].append(e)
def pop(self):
if self.current_stack > 0 and len(c[self.current_stack]) == 1 :
popped = self.c[self.current_stack].pop()
self.current_stack -= 1
return popped
elif self.current_stack == 0 and len(c[self.current_stack]) == 0:
raise IndexError("No more elements to pop.")
else:
return self.c[self.current_stack].pop()
def __repr__(self):
return print(self.c)
st = SetOfStacks(10)
for i in range(21):
st.push(i)
st
Result:
defaultdict(<class 'list'>, {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]})
You are missing self
in the len()
call in push()
:
def push(self, e):
if len(c[self.current_stack]) + 1 > self.size: #####
^
You need:
def push(self, e):
if len(self.c[self.current_stack]) + 1 > self.size: #####
You must have another c
in the environment that you are referencing that is never being added to - so is constantly the same size.
And there are a couple of similar errors in pop()
, e.g.:
def pop(self):
if self.current_stack > 0 and len(c[self.current_stack]) == 1 :
^
Note: def __repr__():
should return a str
not actually print()
, e.g.:
def __repr__(self):
return repr(self.c)
With those fixes you get the expected output:
defaultdict(<class 'list'>, {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
2: [20]})