CS 211 Homework 2 (Regular Stream)
Solution
Comments:
This was a
very difficult assignment. To keep
grading consistent, we ran each program with several inputs:
1.
2.
3
3.
g x y
+
4.
3 x y
+ 1
5.
3 x +
6.
3 3b
7.
3 x
1.5 + y 2 + +
8.
3 x
1.5 – y 2 - -
9.
3 x
1.5 “*” y 2 “*” “*”
10.
3 x
1.5 / y 2 / /
11.
3 x
2.5 + 11 x y - / “*”
In case 1, there is simply no input. You should
print out appropriate error messages for cases 1 to 6, and you should print out
the correct matrix for cases 7 to 11. Each case is worth 5 points.
The rest of the points were spread into
parts where the graders try their best to give you points wherever possible
while being consistent with what was stated on the homework sheet.
Solution:
import
java.util.*;
/**
* This interface 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 {
private Object[] commands;
/**
* Create a function defined by a String
array.
* @param args the String array; a
postfix function in x and y
*/
public StringFunction (String[] args) {
commands = new Object[args.length];
for (int i=0; i<args.length; i++)
{
/**
* same as: if (args[i].equals("+") ||
args[i].equals("-")
* ||
args[i].equals("*") || args[i].equals("/")
* ||
args[i].equals("x") || args[i].equals("y"))
* commands[i] =
args[i];
*/
if (args[i].length() == 1)
switch
(args[i].charAt(0)) {
case '+':
case '-':
case '*':
case '/':
case 'x':
case 'y': commands[i] =
args[i]; continue;
}
try {
commands[i] =
Double.valueOf(args[i]);
}
catch (NumberFormatException
e) {
System.out.println
("\"" + args[i] + "\" is not in the appropriate
format.");
System.exit(-1);
}
}
}
/**
* 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) {
Stack argStack = new Stack();
try {
for (int i=0;
i<commands.length; i++) {
if
(commands[i].equals("x")) //
check for x
argStack.push(new
Double(x));
else if (commands[i].equals("y")) // check for y
argStack.push(new
Double(y));
else if
(commands[i].equals("+")) { // check for Plus
double
rhs=((Double)argStack.pop()).doubleValue();
double
lhs=((Double)argStack.pop()).doubleValue();
argStack.push(new
Double(lhs + rhs));
}
else if
(commands[i].equals("-")) { // check for Minus
double
rhs=((Double)argStack.pop()).doubleValue();
double
lhs=((Double)argStack.pop()).doubleValue();
argStack.push(new
Double(lhs - rhs));
}
else if
(commands[i].equals("*")) { // check for Multiply
double
rhs=((Double)argStack.pop()).doubleValue();
double
lhs=((Double)argStack.pop()).doubleValue();
argStack.push(new
Double(lhs * rhs));
}
else if
(commands[i].equals("/")) { // check for Divide
double
rhs=((Double)argStack.pop()).doubleValue();
double
lhs=((Double)argStack.pop()).doubleValue();
argStack.push(new
Double(lhs / rhs));
}
else
argStack.push(commands[i]); // otherwise it's a number
}
}
catch (EmptyStackException e) {
System.out.println
("Error: Ran out of values to pop from stack!");
System.exit(-1);
}
if (argStack.size() > 1) {
System.out.println
("Error: Evaluation completed but stack contains more than just the
result.");
System.exit(-1);
}
return
((Double)argStack.pop()).doubleValue();
}
public int argCount() {return 2;}
public double evaluate (double[] args) {
if (args.length >= 2)
return evaluate (args[0],
args[1]);
else {
System.out.println ("not enough
arguments to evaluate");
System.exit(-1);
}
}
}
/**
* 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)
{
/**
* Check parameters
*/
if (args.length == 0) {
System.out.println ("Error: Please supply arguments.");
System.exit(-1);
}
if (args.length == 1) {
System.out.println ("Error: Please supply the post-fix
function.");
System.exit(-1);
}
/**
* Extract the size of the matrix
*/
int size = 0;
try {
size = Integer.parseInt(args[0]);
}
catch (NumberFormatException e) {
System.out.println ("First command line input must describe
the size of the matrix.");
System.exit(-1);
}
/**
* Remove the size from the actual commands
*/
String[] commands = new String [args.length - 1];
for (int i=1; i<args.length; i++)
commands[i - 1] = args[i];
/**
* Create a StringFunction based on the arguments and evaluate it
* to fill in the matrix, and then print out the matrix.
* Note: It is optional whether students choose to store the matrix
before printing.
*/
StringFunction sf = new StringFunction (commands);
for (int y=0; y<size; y++) {
for (int x=0; x<size; x++)
System.out.print (sf.evaluate(x,y) + "
");
System.out.println();
}
}
}