Objectives and Overview: Stacks and queues are special linear data structures that restrict the way in which elements can be added and deleted. Yet, these simple data structures have surprisingly wide utility in computer science and modeling applications. We shall explore the properties and some of the applications of stacks and queues in this lab.
Start CodeWarrior and create a new project called Lab6.µ on the desktop. Make a copy of the MazeRunner.java program file from the CS210 (Tucker) -> examples folder and add it to your project. Also copy and add the file structure.zip, which can be found in the CS210 (Tucker) folder, to your project.
To run this program, add a copy of the file fig8.8 from the CS210 (Tucker) folder to your project folder (not your project), and be sure that the Edit -> Target Settings have MazeRunner as the main class and fig8.8 as the parameters.
Now make and run this program to be sure that it works. A sample output of the program for the input maze in Figure 8.8 is shown below:
#################### #s# #f...#...# #.####### ####.#.#.# #.........#..#.###.# ##### ###.#........# # # #...#######.## # # #.### #...#..# # # #.#...#.#.##.# # #...#...#....# ####################
Here, each position of the maze is identified by an integer pair, [i] [j], denoting its row and column number. The starting position is marked with an s and the finishing position is marked with an f. The above display shows a solution by a series of dots (.) from the starting position to the finishing position. In this example, the starting positon is [1] [1] and the finishing position is [1] [11], and the solution path visits positions [2] [1], [3] [1]. [3] [2], [3] [3], and so forth.
Two auxiliary classes are used to facilitate this program, the Maze class and the Position class. The Maze class takes care of reading a maze from an ASCII text file, and also identifies whether a position in the maze is clear or has already been visited. Its methods are summarized on page 141 of your text. The Position class facilitates identifying neighboring positions for any given position, as well as comparing two positions to see if they are the same. Its methods are also summarized on page 141.
The main class in this problem is the Stack. It is used to store all positions that have been already visited in the search for a solution, as well as all positions that are candidates for backtracking when the current path leads to a dead end. Using a trace of the stack during a run of the program, or alternatively using the Debugger and single-stepping through the loop in this program, answer the following questions.
A Polish expression is an alternative way of writing an ariithmetic expression that allows a simple left-right evaluation strategy, as well as the elimination of the need for parentheses and operator precedence. Polish expressions can be simply defined as follows:
Note that this definition is recursive. That is,we can build arbitrarily long Polish expressions from simpler ones by repeatedly applying this definition. Here are some examples, along with their ordinary (infix) interpretations on the right:
|
|
|
|
A number of observations follow from these examples. First, each Polish expression has only one interpretation in terms of the above definition. The second example, for instance, is a Polish expression only if 3 is identified as P1 in the definition, 4 5 - is identified as P2, and - is identified as op. Since part A of the definition allows 3 to be a Polish expression (that's the "base case"), and Part B can be used (recursively) to assure that the subexpression 4 5 - is a Polish expression, the definition allows that the entire expression 3 4 5 - - is a Polish expression.
The second observation that we note from these examples is that there is no need to consider operator precedence or use parentheses when writing a Polish expression. The Infix expressions for the third and fifth examples in this list illustrate this point. The third example uses the fact that equal-preedence operators (- and -) are evaluated from left to right, while the fifth uses the fact that adjacent operators with different precedence (+ and *) are evaluated in order of precedence (* before +).
The third and most important observation we can draw from these examples is that the evaluation of a Polish expression can take place in a single left-right scan, using the assistance of a stack to store operands and intermediate results. This is not possible for infix expressions, whose evaluation may require many scans forward and backward before it is fully evaluated (see the last example in the above list, for instance).
Here's how the evaluation works. The program should have a Stack S for holding operands and intermediate results and a String nextWord for holding the next operand or operator in the input. The following steps are repeated in a loop until the end of the expression is reached:
If these steps are followed carefully, the stack S should contain the final value of the expression when the loop terminates.
Design and implement a program class called EvalPolish that will evaluate any Polish expression using this strategy. The file name for this program should be lab6yourname.java.
Not all sequences of operators and operands are valid Polish expressions. For instance, if the number of operators is not exactly one less than the number of operands or else the operators are misplaced, the expression is not valid. Moreover, if any string in the expression is not either an operator or an operand, the evaluation cannot proceed.
Submit your Java program from Part 2 of this lab by dragging it to the Drop Box folder. Also hand in a hard copy listing of your program, along with your answers to the questions in Parts 1 and 3.
You may work on the programming parts of this lab in teams of two, but all answers to the questions should be developed individually.