CS211 Homework 2
Watch
this space for updates!
Post-Fix Function Evaluator
Concepts
you should understand:
Multi-dimensional Arrays
Interfaces
Inheritance
Stack
Postfix Machines (refer to your
textbook, section 11.2.1)
Input:
Input is entirely by command-line arguments. The first
argument describes the size (e.g. the length of one side) of a square. The
remaining arguments are the postfix commands to a simple post-fix stack machine
for evaluating a function. These commands describe a function in x and y in
postfix notation. For example, the
function
f(x,y) = x^2 + y^2 + 1 could be represented as:
x x * y y * + 1 +
You
will need to use java.util.Stack. Each variable or number is simply pushed onto
the stack. Each operation takes the top two stack items and replaces them with
the result of the operation. Be careful
about the order in which stack items are processed when doing subtraction or
division. For instance you should check
your code to make sure that “4 3 –” evaluates as 1 and not –1.
For
command line parsing: The command line arguments (separated by spaces) are
automatically divided into an array of String (i.e., the argument to the main()
method) where each element of the array is a String that is either an operation
(+,-,*,/) or a number or a variable (x,y). Any token longer than one character
should be a number. The one-character
tokens can be easily checked to see what category they're in. Note that the
numbers can have decimal points (see the java.lang.Double.valueOf( )
method). For simplicity, all numbers
are assumed to be of type double.
Errors:
If
the input arguments are not in the proper format then you should print an
appropriate error message. To do this,
you will need to catch exceptions (e.g., Double.valueOf throws a
NumberFormatException). An appropriate error message means your program must be
able to tell what kind of error it is. This includes: bad number format, stack
has more than one element after evaluating the function, and not enough
elements in the stack. When using
numbers of type double, division by zero produces + or – infinity in Java; your
program can do the same.
Output:
If you invoke your program with the following command-line arguments:
3 x 3 + y 1 - * 2 / 10 +
then
the first 3 should cause your program to create a 3 by 3 matrix. The remaining commands describe a function
that is invoked on each index-pair of the matrix. The result of the function is stored in the matrix. In other words, the command-line arguments
describe a function f(x,y). The value
of f(i,j) is stored in matrix[i,j]. In
the output for the example, the top right of the matrix corresponds to x=2 and
y=0 and f(x,y) = 7.5
Your
output should be:
8.5 8.0 7.5
10.0 10.0 10.0
11.5 12.0 12.5
Efficiency:
Your code should be efficient. In particular, your code shouldn’t convert a
string (e.g., “1.5234”) into a double each and every time the function is
evaluated.
Double.valueOf(
) is expensive compared to Double.doubleValue( ). The first method takes a String and returns the equivalent
double. The second method returns the
value of a double stored within a Double.
The class Double is a wrapper class (see page 95 in the text). It exists as a convenient way to store a
double (a primitive type) so that it can be used as an Object.
A
function is evaluated several times as the matrix of values is filled in. It’s very inefficient if every number in the
postfix definition of the function is converted from a String into a double
each and every time the function is evaluated.
It’s more efficient to convert each number just once, when it’s first
recognized as a number. Once it has
been converted to a double, it can be “wrapped” (use: “new Double(double);” to
create an Object that holds a double), and then stored in, for instance, a
Vector (see java.util.Vector) along with the operators.
How
your program will be graded:
We
will run your program with our own post-fix commands which will be designed to break
your program. This comprises 80% of the assignment grade. Make sure you print
your matrix as in the example so we can compare yours to ours. Partial credits
will be awarded if the graders can understand your code (e.g. please write
comments!!). The other 20% will be your style and efficiency.
Code
skeleton:
import java.util.*;
/**
* Handles functions that take an unspecified
number of arguments
*/
interface Function {
/**
* Returns the number of arguments that this
Function takes.
* @return number of arguments this function
uses
*/
public int argCount();
/**
* Evaluate the Function.
* @param args the arguments to the function
* @return the value of the function
evaluated on the given arguments
* @exception IllegalArgumentException is
thrown for wrong number of arguments
*/
public double evaluate (double[] args);
}
/**
* This interface handles functions that take
exactly two arguments.
*/
interface Function2
extends Function {
/**
* Evaluate the function.
* @param x the first argument to the
function
* @param y the second argument to the
function
* @return the value of the function
evaluated on x and y
*/
public double evaluate (double x, double y);
}
/**
* This class implements a function in x and y
defined by a String array.
*/
class StringFunction
implements Function2 {
/**
* Create a function defined by a String
array.
* @param args the String array; a
postfix function in x and y
*/
public StringFunction (String[] args) {
// Todo: Initialize a StringFunction and throw exceptions when needed
}
/**
* Evaluate the function.
* @param x the first argument to the
function
* @param y the second argument to the
function
* @return the value of the function
evaluated on x and y
*/
public double evaluate (double x, double
y) {
// Todo: Evaluate the function using
x and y, throwing exceptions when needed
}
// Todo: You will need at least one other method.
}
/**
* This class takes an array of arguments as
Strings from command line and parses
* them to create a matrix populated with
functions on the indices of the matrix.
*/
public class
Evaluator {
public static void main (String[] args) {
// Todo: If input is wrong, you need
to produce a reasonable error message
// Extract the size of the matrix
int size =
Integer.parseInt(args[0]);
// Todo: You may need to process the
arguments first.
// Todo: Create a StringFunction based on the arguments
and evaluate it
// to fill in the matrix, and then print out the matrix.
}
}