Solution for Midterm

Problem 1

The coordinates of any point in a rectangular grid are two integers. The X-coordinate increases going East along the X-axis, and the Y-coordinate increases going North along the Y-axis. You are to implement a class Point subject to the following guidelines: Solution:
class Point implements PointI {
  private int xcoord, ycoord;

  public Point (int x, int y) { xcoord=x; ycoord=y; }

  public int getX () { return xcoord; }
  public int getY () { return ycoord; }

  public void moveNorth () { ycoord++; }
  public void moveSouth () { ycoord--; }
  public void moveEast ()  { xcoord++; }
  public void moveWest ()  { xcoord--; }

  public int distance (Point p) {
    int px = p.getX();
    int py = p.getY();
    int distance = 0;
    distance = distance + Math.abs(xcoord - px);
    distance = distance + Math.abs(ycoord - py);
    return distance;
  }

  public String toString () {
    return "X= " + xcoord + ", Y= " + ycoord;
  }

}


Problem 2

In the following code, write next to each println statement either: Solution:
class A {
  int x, y;
  A () { x=1; y=2; }
  int getx () { return x; }
}

class B extends A {
  int x, z;
  B () { super(); x=3; y=4; z=5; }
  int getx () { return x; }
  int getz () { return z; }
}

class Prob1 {
  public static void main (String[] args) {
    A o1 = new A();
    A o2 = new B();
    B o3 = new B();

    System.out.println(o1.x);      // 1
    System.out.println(o1.getx()); // 1
    System.out.println(o1.y);      // 2
    System.out.println(o1.getz()); // does not compile

    System.out.println(o2.x);      // 1
    System.out.println(o2.getx()); // 3
    System.out.println(o2.y);      // 4
    System.out.println(o2.getz()); // does not compile

    System.out.println(o3.x);      // 3
    System.out.println(o3.getx()); // 3
    System.out.println(o3.y);      // 4
    System.out.println(o3.getz()); // 5
  }
}

Problem 3

Write a method with the following declaration:
String readS (StreamTokenizer st) throws ioE;
The method should attempt to read a word from the StreamTokenizer object st. If unsuccessful for any reason, the method should throw an ioE exception. You may assume that the class ioE is already defined as follows:
class ioE extends Exception {
  ioE (String s) { super(s); }
}
Solution:
  String ReadS (StreamTokenizer st) throws ioE {
    try {
      st.nextToken();
      if (st.ttype == st.TT_WORD) {
	return st.sval;
      }
      else throw new ioE("Need a string");
    }
    catch (IOException e) { throw new ioE("Error"); }
  }

The following is also acceptable:
  
  String ReadS (StreamTokenizer st) throws ioE {
    try {
      st.nextToken();
      if (st.ttype == st.TT_WORD) {
	return st.toString();
      }
      else throw new ioE("Need a string");
    }
    catch (IOException e) { throw new ioE("Error"); }
  }

Problem 4

Write class definitions that reflect the following relationships: Provide each Shape object with an operation to compute its area, and an operation to compute its perimeter. Your code should be written such that the following program works as specified:
class Simple {
  public static void main (String[] args) {
    Shape s = new Square(3.2);     // constructs a square with side 3.2
    Shape c = new Circle (2.9);    // constructs a circle with radius 2.9
    System.out.println(s.area());  // prints 10.240000000000002
    System.out.println(s.perim()); // prints 12.8
    System.out.println(c.area());  // prints 26.420794216690158
    System.out.println(c.perim()); // prints 18.2212373908208
  }
}
Solution:
abstract class Shape {
  abstract double area();
  abstract double perim();
}

class Square extends Shape {
  private double s;

  Square (double s) { this.s =s; }

  double area () { return s*s; }
  double perim () { return s*4; }
}


class Circle extends Shape {
  private double r; 

  Circle (double r) { this.r = r; }

  double area () { return Math.PI * r*r; }
  double perim() { return 2*Math.PI*r; }
}

Problem 5

Write class definitions that reflect the following relationships: Every Shape object should have a method accept that takes a ShapeOp argument. Every ShapeOp object should have two methods: one that works on Square objects and one that works on Circle objects. Your code should be written such that the following program works as specified:
class Advanced {
  public static void main (String[] args) {
    Shape s = new Square (3.2);
    Shape c = new Circle (2.9);
    ShapeOp perim = new PerimOp();
    ShapeOp area = new AreaOp();
    System.out.println(s.accept(area));  // prints 10.240000000000002
    System.out.println(s.accept(perim)); // prints 12.8
    System.out.println(c.accept(area));  // prints 26.420794216690158
    System.out.println(c.accept(perim)); // prints 18.2212373908208
  }
}
Solution:
abstract class Shape {
  abstract double accept (ShapeOp op);
}

class Square extends Shape {
  double s;
  Square (double s) { this.s = s; }
  double accept (ShapeOp op) {
    return op.square(this);
  }
}

class Circle extends Shape {
  double r; 
  Circle (double r) { this.r = r; }
  double accept (ShapeOp op) {
    return op.circle(this);
  }
}

abstract class ShapeOp {
  abstract double square (Square sq);
  abstract double circle (Circle ci);
}

class AreaOp extends ShapeOp {
  double square (Square sq) { return sq.s * sq.s; }
  double circle (Circle ci) { return Math.PI * ci.r * ci.r; }
}

class PerimOp extends ShapeOp {
  double square (Square sq) { return sq.s * 4; }
  double circle (Circle ci) { return 2* Math.PI * ci.r; }
}

Extra Credit

The Fibonacci sequence is defined as follows: the first element is 0, the second element is 1, and then every element is the sum of the previous two. For example, the first few elements are:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
Write a Java method fib that takes an integer argument n and returns the nth element of the Fibonacci sequence.

Solution:

  int fib (int i) { 
    if (i==1) return 0;
    else if (i==2) return 1;
    else return fib(i-1)+fib(i-2);
  }

Visited times since December 15, 1997 (or the last crash).

sabry@cs.uoregon.edu