(Latest Revision: 09/12/2000)

Hints to Help You Implement the Stack


CONSIDER DECIMAL DIGIT SELECTION:

Suppose you have a decimal display with a capacity of 8 digits. You can then display a number such as:

12938761

If you wish, you can think of this as a stack with 4 numbers on it: 61, 87, 93, and 12.

You can start with an original value of

00000000

When you want push 12 onto the stack, you put the 12 into the rightmost two digits:

00000012

When you want to push 93 onto the stack that already contains 12, you shift the 12 over to the left and put the 93 into the rightmost two digits:

00001293

It's similar to push 87 and then 61

00129387

12938761

If the display is limited to 8 digits, then there is no more room for more elements to be pushed onto the stack.

At first you may think that you can store any set of four two-digit numbers this way. However what does 00000000 mean? Is this an empty stack or is this a full stack that contains four zeros?

One way to get around this ambiguity is to let 00000000 represent an empty stack, and to agree that we will place only numbers in the range 01-99 on the stack.

How can we program instructions to place an element on the stack? There is a really easy way to do it with arithmetic. For example we can push 87 onto 00001293 by just multiplying by 100 and adding 87:

00001293*100+87 equals 00129387

It is also easy to pop something using the % and / operators. For example,

00129387 % 100 equals 87 (the top element of the stack), and

00129387 / 100 equals 00001293 (the stack after the top has been popped off-- assuming that C-style integer divsion has "thrown away" the decimal part.)

How can you test to see if the stack is full? The biggest number you can express with 8 digits is 99999999 (99,999,999). Suppose you want to push 25 onto the stack. If stack*100+25 is more than 99,999,999 then there is no room. Basically if you don't have room to push 99, then the stack is full. So you just need to check to see if stack*100+99 is more than 99,999,999.


MODIFY IT TO WORK ON CHARACTERS:

The idea above works well when you are interested in storing numbers in the range 1-99. It can also work when you want to store characters in the range 'a'-'z'. One could use exactly the scheme described above, except just push numbers in the range 1-26 and ignore the numbers from 27-99. However this wastes space. This stack will probably have a smaller-than-optimal capacity. (Remember: The program specifications require that your implementation have room for at least six characters when the program is compiled and executed on the Sun Ultra's.)

You can conserve capacity better by using a smaller "modulus." There is really nothing special about using modulus 100.

At first glance the stack operations are easier to understand when the modulus is a power of 10. That is because we are accustomed to representing numbers in base-10 notation. However, it's easy to use the same idea with a different type of modulus. For example, it will work to push by doing data=data*27+code, where code is in the range 1-26.

Of course, in this case the stack top is data%27, and if you pop the stack the new stack is data/27.

The actual number you will be working with (the class member called data) is an unsigned long int. The maximum value it can store is a constant called ULONG_MAX, which is defined in "limits.h". The actual value of ULONG_MAX can vary from system to system. Mainly the issue is how many bits are allocated to representing an unsigned long int. The more bits, the larger the number can be before it overflows.

Basically you can test for a full stack by seeing if data*27+26 > ULONG_MAX. However you have to make sure that in the course of doing your test you don't overflow something that the computer is storing as an unsigned long int. In other words, don't directly tell the computer to compute data*27+26 because this will sometimes cause an overflow. If an overflow occurs, the result of the test will not be reliable. Instead, cast data to a double first. After that it is safe to multiply by 27 and add 26.