Q1: 20 points Q2: 10 points Q3: 15 points Q4: 15 points Q5: 10 points Q6: 10 points Q7: 20 points Total: 100 points
import java.util.*; // we will use Stack
public class Dog {
private String name;
private int age;
public Dog (String newName, int newAge) {
name = newName;
age = newAge;}
public String getName {return name;}
public void setName (String newName) {name = newName;}
public int getAge ( ) {return age;}
public void setAge (int newAge) {age = newAge;}}
Question 7 uses this generic class from DJW:
public class LLNode<T> {
private LLNode link;
private T info;
public LLNode (T info) {this.info = info; link = null;}
public void setInfo (T info) {this.info = info;}
public T getInfo( ) {return info;}
public void setLink (LLNode link) {this.link = link;}
public LLNode getLink ( ) {return link;}}
String [ ]
and String [ ] [ ]
A String [ ]
is a one-dimensional array of Strings. A
String [ ] [ ]
is a two-dimensional array of Strings.
ArrayStringLog( )
and ArrayStringLog (int k)
constructors in DJW
The first constructor sets up an array of the default size, while the second sets up an array of length k. These sizes are the maximum number of strings the StringLog can hold without being full.
Software is the totality of code, protocols, and documentation that solve an information processing task. Code is just the code -- instructions to a machine in a computer language.
O(1) running time is bounded by a constant independent of the input size -- no matter how long the input is, the time will be bounded by some fixed limit. O(n) running time grows at most proportionally to the input size -- there is some number c such that the running time is never more than cn on input of length n.
ArrayStringLog
(DJW) and StringBag
(Project #1) classes
The StringLog ADT is a collection of Strings that supports insertion (at the end), reporting size, and testing whether a particular String is a member. The StringBag ADT is a collection of Strings that supports insertion at the end and removal of a random element. The two classes mentioned are each array implementations of their ADT's.
Postfix expressions like 3 2 *
have the operator after
the operands on which it operates. Infix expressions like 3
* 2
have the operator between the operands.
Guarding against an exception is preventing it from happening by testing for the condition that causes it before running the code that would cause it. Catching the exception is allowing it to occur within a try block, when there is a matching catch block afterward with code to be run after the exception occurs.
pop
in java.util.Stack
and pop
in DJW's stack classes
In the java.util.Stack
class a pop operation removes
and returns the top element of the stack. In the DJW stack
classes, the pop operation removes the top element without returning it.
An object is an entity containing data in its fields and able to run
the methods defined in its class. A primitive is a member of one of
the eight basic data types of Java (six for numbers,
char
, and boolean
). Primitives are passes
by value, and objects by reference.
An observer is an instance method that returns information about the object without changing its state. A transformer is an instance method that changes the state of the object.
StringBag
called replace
, which takes a String
as a
parameter and
replaces a randomly-chosen element of the bag with the parameter, keeping all
the other elements in the same position.
The replace
method would be much like the zero-parameter
remove
method, in that it would use a pseudorandom
number to choose a random element of the array (in the range of
indices actually used for elements) and remove it. But it would
replace the new element with its parameter, rather than with the
last element in the used range.
isUnique
to
SudokuSolver
that takes a Board
as a parameter and
returns a boolean that is true
if the Board
denotes
a puzzle with one and only one solution. (The return value should be
false
if there is no solution or if there are more than one.)
It would be easy to modify the backtrack search of
SudokuSolver
so that instead of stopping when it
finds a solution, it would go on to the next value for the last
cell and continue, until it either finds a second solution (and
returns false) or empties its stack (and returns true). Of course
if it empties the stack before finding a solution it should return false.
Dog
class from above is present.
Include a brief justification of your answer.
// uses java.util.Stack names for methods
// Missing parens added 28 Sept 2014
Stack<Dog> left = new Stack<Dog>( );
Stack<Dog> right = new Stack<Dog>( );
right.push(new Dog("Duncan", 3)):
right.push(new Dog("Biscuit", 3));
right.push(new Dog("Cardie", 5));
right.push(new Dog("Ace", 6));
Dog newDog = new Dog("Sydney", 3));
while (!right.empty( ) && (right.peek( ).getAge( ) > newDog.getAge ( ))
left.push(right.pop( ));
right.push(newDog);
System.out.println(left.peek( ).getName( ));
We first push four dogs onto the right stack. We then shift dogs from
the right to the left as long as the dogs are older than
Sydney. Ace and Cardie are shifted, then Biscuit is not. We
puch Sydney only the right stack (which now has, from the top,
Sydney, Biscuit, and Duncan) and prime the name of the top dog
on the left stack, which is "Cardie"
.
int [ ] row = new int[9];
for (int i = 0; i < 9; i++)
row[i] = i + 1;
boolean duplicate = false;
for (int j = 0; j < 9; j++)
for (int k = 0; k < 9; k++)
if (row[j] == row[k]) duplicate = true;
if (duplicate)
System.out.println ("Duplicate element exists");
else System.out.println ("Elements are unique");
We make an array of nine ints and fill them with the numbers 1 through
9. We then go through all pairs of indices in this array,
looking for any case in which the two indices have the same
value. Since these loops include the case of teaching an index
against itself, we find lots of matches and the badly-named
variable duplicate
is set to true. Thus we print
"Duplicate element exists"
although this is not
true in the normal meaning of the word.
Dog ace = new Dog ("Ace", 6);
Dog biscuit = new Dog ("Biscuit", 3);
Dog cardie = new Dog ("Cardie", 5);
Dog golden = cardie;
Dog pointer = ace;
pointer.setName("Cardie");
golden.setName(ace.getName( ));
biscuit.setName(cardie.getName( ));
pointer.setName("Biscuit");
System.out.println(ace.getName( ));
System.out.println(cardie.getName( ));
Five dog variables are defined, but only three dogs are created. To
keep it straight, we'll refer to the dogs by their ages. After
the first five lines, ace
and pointer
point to the age-6 dog, biscuit
points to the age-3
dog, and cardie
and golden
both point
to the age-5 dog. We then rename the age-6 dog to
"Cardie"
in the sixth line. The seventh line
changes nothing because it sets the age-5 dog's name to
"Cardie"
, which it already was. The eighth line
sets the age-3 dog's name to "Cardie"
as well. Then
the ninth line renames the age-6 dog as "Biscuit"
.
The variable ace
still points to the age-6 dog, so
we print out "Biscuit"
. The variable
cardie
still points to the age-5 dog, so we print
out "Cardie"
.
public class Group<T> {
private T [ ] elements;
public Group ( ) {
elements = new T[100];}}
The last line causes a compiler error because you cannot create an array of a generic type. You have to create an array of Objects and cast it into the generic type.
ArrayStack as = new ArrayStack (10);
as.push (new Dog ("Ace", 6));
as.push (new Dog ("Biscuit", 3));
as.push (new Dog ("Cardie", 5));
while (as.top( ) != null)
as.pop( );
as.push (new Dog ("Cardie", 5));
We put three dogs on the stack and start popping them off until there
are none left. But after the third dog is popped, we call the
method top
on an empty stack, throwing a
StackUnderflowException
. The programmer
presumably meant to say while (!isEmpty( ))
.
Integer [ ] ia = new Integer [10];
for (int i = 0; i < 5; i++)
ia[i] = i;
for (int j = 0; j < ia.length; j++)
ia[j]++;
We create an array with room for ten Integers, and create objects for
the first five locations by autoboxing in the first loop. The
second loop goes fine for the first five locations because the
Integer is unboxed, incremented, and boxed. But the attempt
to increment ia[5]
throws a
NullPointerException
because this location is
still null
.
LinkedStringLog
class)
public int sumLengths ( ) {
int sum = 0;
LLStringNode cur = log; // "log" is the head of the list of N elements
while (cur != null) {
sum += cur.getInfo( ).length( );
cur = cur.getLink( );}
return sum;}
This takes O(N) time in the while loop because we go through the loop once for each element of the list, and the inside of the loop does the same set of operations no matter how long the list is. The operations outside the loop also take O(1) time, and O(N) + O(1) = O(N).
// create a Board object b with all cells unfixed
// read an array of N Move objects and call b.move( ) for each
// set all nonzero elements of b to be fixed
// solve the resulting sudoku puzzle using the solution to Project #2
Because 9 is a constant, any operation on a 9 by 9 board, even something as complicated as solving the Sudoku puzzle, takes constant time (maybe a large constant) as it does not depend on the number N. But applying the Move objects to the Board takes O(1) time for each object, or O(N) time total. (Note that if there are more than 81 Moves, some of them are going to reset numbers that have been set by previous Moves.) The total time is thus O(N) + O(1) = O(N).
Kennel
so that each Kennel
object will
have an array dogs
of Dog
objects, and an
int
variable size
that will keep track of how
many dogs are in the array. Don't worry about error handling -- if bad input
to one of your methods causes an exception, that is fine. The class should
have the following methods:
Kennel (int k)
that creates an object that can
hold up to k Dog
objects,
boolean
method free (int pos)
that tells
whether position pos
now has no Dog
in it,
void
method insert (Dog d, int pos)
that
puts d
into position pos
if it is free, and does
nothing if it is not,
remove (int pos)
that removes and returns the
Dog
in position pos
, or returns null
if there is no Dog
there, and
void
method consolidate
that moves all
the Dog
objects to an initial segment of the locations -- to
locations 0
through size - 1
, where size
is the number of Dog
objects currently stored.
public class Kennel {
Dog [ ] dogs;
int size;
public Kennel (int k) {
dogs = new Dog[k];
size = 0;}
public boolean free (int pos) {
return (dogs[pos] == null);}
public void insert (Dog d, int pos) {
if (free(pos)) {
dogs[pos] = d;
size++;}
public Dog remove (int pos) {
Dog out = null;
if (!free(pos)) {
out = dogs[pos];
dogs[pos] = null;
size--;}
return out;}
public void consolidate( ) {
int scan = 0;
for (int i = 0; i < size; i++) {
while (free(scan)) scan++;
dogs[i] = dogs[scan]; // copying higher to lower index
dogs[scan] = null;}}} // position will be null and be skipped
Dog
objects. An
AscendingAgeDogList
must have the property that every
Dog
in it has an age less than or equal to that of any
Dog
following it. A DescendingAgeDogList
has the
opposite property, that every Dog
in it has an age greater than
or equal to that of any Dog
following it. (You may abbreviate
these classes as AADL
and DADL
.)
(Note: These two classes are obviously going to be similar to each other. You may save yourself writing by designing one of them, and then clearly indicating what has to be changed to get the other.)
Using the LLNode<Dog>
class from above, define each class
to have the following methods:
void
method add (Dog d)
that puts
d
d at the head of the list if that meet's the list's
conditions, and does nothing otherwise,
boolean
method canAdd (Dog d)
that tells
whether d
may legally be added at the front of the list,
remove( )
that removes and returns the
Dog
from the head of the list, returning null
if the
list is empty, and
void
method insert (Dog d)
that inserts
d
into the list at the first legal place.
(Hint: The most difficult method to implement is insert
.
But you can do it by removing the objects that are in the way of the place
to insert, and storing them in an object of the other class.)
public class AADL {
LLNode<Dog> top;
public AADL ( ) {
top = null;}
public void add (Dog d) {
if (isEmpty( ) || d.getAge( ) <= top.getAge( )) {
LLNode<Dog> newNode = new LLNode<Dog> (d);
newNode.setLink(top);
top = newNode;}}
public void canAdd (Dog d) {
return (isEmpty( ) || d.getAge( ) <= top.getAge( ));}
public Dog remove( ) {
// throws NullPointerException if list is empty
Dog out = top.getInfo( );
top = top.getLink( );
return out;}
public boolean isEmpty( ) {
return (top == null);}
public void insert (Dog d) {
DADL storage = new DADL (dogs.length);
while (!canAdd(d))
storage.add(remove( ));
add(d);
while (!storage.isEmpty( ))
add(storage.remove( ));}}
public class DADL {
LLNode<Dog> top;
public DADL ( ) {
top = null;}
public void add (Dog d) {
if (isEmpty( ) || d.getAge( ) >= top.getAge( )) {
LLNode<Dog> newNode = new LLNode<Dog> (d);
newNode.setLink(top);
top = newNode;}}
public void canAdd (Dog d) {
return (isEmpty( ) || d.getAge( ) >= top.getAge( ));}
public Dog remove( ) {
// throws NullPointerException if list is empty
Dog out = top.getInfo( );
top = top.getLink( );
return out;}
public boolean isEmpty( ) {
return (top == null);}
public void insert (Dog d) {
AADL storage = new AADL (dogs.length);
while (!canAdd(d))
storage.add(remove( ));
add(d);
while (!storage.isEmpty( ))
add(storage.remove( ));}}
Last modified 28 September 2014