CIS 121 April 6, 2000
Examining Stacks
Today you will get a chance to examine the implementation of the
methods of a Stack. Recall that we discussed the class Stack which is
in the java.util package. The interface of the class is
public class Stack extends Vector {
public Stack();
public boolean empty();
public Object peek();
public Object pop();
public Object push(Object item);
public int search(Object o);
}
This class is implemented using Vectors. We have discussed what Vectors
are. We looked at the following example of using a Stack.
import java.util.*;
public class ReversePolishNotation {
String inputString;
String outputString = "";
public ReversePolishNotation(String s) {
inputString = s;
}
private int priority(String s) {
int operatorPriority = -1;
if (s.equals("["))
operatorPriority = 0;
else if (s.equals("("))
operatorPriority = 1;
else if (s.equals("+"))
operatorPriority = 2;
else if (s.equals("-"))
operatorPriority = 2;
else if (s.equals("*"))
operatorPriority = 3;
else if (s.equals("/"))
operatorPriority = 3;
else if (s.equals("^"))
operatorPriority = 4;
return(operatorPriority);
}
private void convert() {
Stack myStack = new Stack();
String nextCharacter;
String topOfStack;
for (int i = 0;i<=inputString.length()-1;i++) {
nextCharacter = inputString.substring(i,i+1);
System.out.println(nextCharacter);
if (nextCharacter.equals(")")) {
topOfStack = (String)myStack.pop();
while (!topOfStack.equals("(")) {
outputString += topOfStack;
topOfStack = (String)myStack.pop();
}
} else if (nextCharacter.equals("]")) {
topOfStack = (String)myStack.pop();
while (!topOfStack.equals("[")) {
outputString += topOfStack;
topOfStack = (String)myStack.pop();
}
} else if (nextCharacter.equals("(") ||
nextCharacter.equals("[")) {
myStack.push(nextCharacter);
} else if (nextCharacter.equals("+") ||
nextCharacter.equals("-") ||
nextCharacter.equals("*") ||
nextCharacter.equals("/") ||
nextCharacter.equals("^")) {
topOfStack = (String)myStack.peek();
while (priority(nextCharacter) <= priority(topOfStack)) {
topOfStack = (String)myStack.pop();
outputString += topOfStack;
topOfStack = (String)myStack.peek();
}
myStack.push(nextCharacter);
} else {
outputString += nextCharacter;
}
}
}
public String toString() {
return(outputString);
}
public static void main(String[] args) {
ReversePolishNotation myConverter = new ReversePolishNotation("[a+b]");
myConverter.convert();
System.out.println(myConverter);
}
}
Download the Source Code and
place it into c:\java.
When this program is compiled and executed it will produce the output
of the algorithm to convert infix notation to Reverse Polish Notation.
Notice that this program uses the Stack class. This is the Stack class
in java.util.
Notice how this reinforces our idea of abstraction. We are using methods
associated with a Stack without any knowledge of how they are
implemented other than the fact that Vectors are used.
What we want to do today is replace these implementation of Stack
methods with arrays.
We began discussing this yesterday in class and looked at the implementation
of the non-destructive Stack methods.
public class Stack {
final int maxSize = 100;
// Since we must declare the size of an array we establish a maximum
// size for the array for this implementation.
Object[] myStack = new Object[maxSize];
// We now create an array of Objects.
Object delimiter = new String(";");
// To determine the bottom of the array we create a delimited and
// stipulate that this Stack will not be sent an Object which is
// the same as the delimiter.
int positionOfDelimiter;
// To easily determine where the bottom entry of the stack is
// we create a integer to point to that position.
public Stack() { // Constructor
myStack[0] = delimiter;
// We place the delimiter at the top of the stack. In this
// implementation, the top of the stack will be position 0.
positionOfDelimiter = 0;
// We also initialize positionOfDelimiter to point to the
// position of the delimiter.
}
public Object peek() { // Implementation of peek
return(myStack[0]);
// Since the peek method is a non-destructive Stack method
// all we need to do is return the Object on top of the
// Stack and not do anything to the Stack.
}
public boolean empty() { // Implementation of empty
return(myStack[0] == delimiter);
// The empty method is also a non-destructive Stack method.
// If the delimiter is at the top of the Stack, then the
// Stack is empty, so we return the result of a logical
// test.
}
public int search(Object o) { // Implemenation of search
int i = 0;
// This is the last non-destructive Stack method. We use a local
// int variable to determine the position of the Object if it is
// found.
while ((myStack[i] != o) && (i<=maxSize))
// Since i is initialized to 0, we begin searching at the top of the
// Stack. As long as the Object is not found and we have not reached
// the bottom of the Stack, we increment i.
i++;
return(i);
// Notice that if the Object is found, then we return the position
// in which it was found. (This was a mistake from yesterday. When
// the Object is located, the while loop will not be entered so the
// Object is in position i.) Notice that if the Object is not found
// the maxSize will be returned. We will stipulate to the calling
// environment that this indicates the Object wasn't found.
}
public Object pop() {
}
public Object push(Object item) {
}
}
For today's lab, implement the two destructive Stack methods. Notice
what has to happen in these methods.
pop
The pop method will take the top Object off the Stack and then adjust
the rest of the Stack up one position. Remember to adjust the position
of the delimiter.
push
The push method will adjust the entire Stack down one position and
then place the Object in position 0. Remember to adjust the position
of the delimiter, and remember that the return type of the method is
Object.
After you have implemented these two methods, place them into the new
Stack class. Make sure that the source code is in c:\java. You may
download the part of the implementation we
did yesterday in class.
After you implement these two methods, recompile ReversePolishNotation.java
and then run it to make sure it produces the same result.