mirror of
https://github.com/ossu/computer-science.git
synced 2026-04-11 02:11:49 +08:00
Lab10
This commit is contained in:
parent
5c3e3909d1
commit
f024d567cf
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Lab10_HashStackIterator</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
@ -0,0 +1,170 @@
|
||||
interface IPred<T> {
|
||||
boolean apply(T t);
|
||||
}
|
||||
|
||||
class MatchToData<T> implements IPred<T> {
|
||||
T match;
|
||||
MatchToData(T match) {
|
||||
this.match = match;
|
||||
}
|
||||
public boolean apply(T t) {
|
||||
return t.equals(match);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ANode<T> {
|
||||
ANode<T> next;
|
||||
ANode<T> prev;
|
||||
ANode(ANode<T> next, ANode<T> prev) {
|
||||
this.next = next;
|
||||
this.prev = prev;
|
||||
}
|
||||
// inserts this node between before and after nodes
|
||||
void insertBetween(ANode<T> next, ANode<T> prev) {
|
||||
if (prev == null || next == null) {
|
||||
throw new IllegalArgumentException("Cannot assign next or prev to null");
|
||||
}
|
||||
prev.next = this;
|
||||
this.prev = prev;
|
||||
this.next = next;
|
||||
next.prev = this;
|
||||
}
|
||||
// inserts this node after provided node
|
||||
void insertAfter(ANode<T> prev) {
|
||||
this.insertBetween(prev.next, prev);
|
||||
}
|
||||
// inserts this node before provided node
|
||||
void insertBefore(ANode<T> next) {
|
||||
this.insertBetween(next, next.prev);
|
||||
}
|
||||
int size() {
|
||||
if (this.next == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.next.sizeHelper(0);
|
||||
}
|
||||
}
|
||||
abstract void remove();
|
||||
abstract int sizeHelper(int cnt);
|
||||
abstract ANode<T> find(IPred<T> p);
|
||||
abstract T getData();
|
||||
}
|
||||
|
||||
class Sentinel<T> extends ANode<T> {
|
||||
Sentinel(ANode<T> next, ANode<T> prev) {
|
||||
super(next, prev);
|
||||
}
|
||||
Sentinel() {
|
||||
this(null, null);
|
||||
this.insertBetween(this, this);
|
||||
}
|
||||
int sizeHelper(int cnt) {
|
||||
return cnt;
|
||||
}
|
||||
ANode<T> removeNext() {
|
||||
if (this.next == this) {
|
||||
throw new RuntimeException("Cannot remove item from empty list");
|
||||
}
|
||||
ANode<T> r = this.next;
|
||||
this.next.remove();
|
||||
return r;
|
||||
}
|
||||
ANode<T> removePrev() {
|
||||
if (this.next == this) {
|
||||
throw new RuntimeException("Cannot remove item from empty list");
|
||||
}
|
||||
ANode<T> r = this.prev;
|
||||
this.prev.remove();
|
||||
return r;
|
||||
}
|
||||
void remove() {
|
||||
throw new RuntimeException("Cannot remove sentinel node");
|
||||
}
|
||||
ANode<T> find(IPred<T> p) {
|
||||
return this;
|
||||
}
|
||||
T getData() {
|
||||
throw new RuntimeException("Sentinels have no data");
|
||||
}
|
||||
}
|
||||
|
||||
class Node<T> extends ANode<T> {
|
||||
T data;
|
||||
Node(T data, ANode<T> next, ANode<T> prev) {
|
||||
super(next, prev);
|
||||
this.data = data;
|
||||
this.insertBetween(prev, next);
|
||||
}
|
||||
Node(T data) {
|
||||
super(null, null);
|
||||
this.data = data;
|
||||
}
|
||||
int sizeHelper(int cnt) {
|
||||
return this.next.sizeHelper(cnt + 1);
|
||||
}
|
||||
void remove() {
|
||||
this.prev.next = this.next;
|
||||
this.next.prev = this.prev;
|
||||
}
|
||||
ANode<T> find(IPred<T> pred) {
|
||||
if (pred.apply(this.data)) {
|
||||
return this;
|
||||
} else {
|
||||
return this.next.find(pred);
|
||||
}
|
||||
}
|
||||
T getData() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
||||
class Deque<T> {
|
||||
Sentinel<T> header;
|
||||
Deque(Sentinel<T> header) {
|
||||
this.header = header;
|
||||
}
|
||||
Deque() {
|
||||
this(new Sentinel<T>());
|
||||
}
|
||||
// returns the number of nodes in a list Deque, not including the header node
|
||||
int size() {
|
||||
return this.header.size(); //
|
||||
}
|
||||
// inserts node n at the front of the list.
|
||||
void addAtHead(Node<T> n) {
|
||||
n.insertAfter(this.header);
|
||||
}
|
||||
// inserts node n at the end of the list.
|
||||
void addAtTail(Node<T> n) {
|
||||
n.insertBefore(this.header);
|
||||
}
|
||||
// returns and removes the first node from this Deque.
|
||||
// Throw a RuntimeException if an attempt is made to remove
|
||||
// from an empty list.
|
||||
ANode<T> removeFromHead() {
|
||||
return this.header.removeNext();
|
||||
}
|
||||
// returns and removes the last node from this Deque.
|
||||
// Throw a RuntimeException if an attempt is made to remove
|
||||
// from an empty list.
|
||||
ANode<T> removeFromTail() {
|
||||
return this.header.removePrev();
|
||||
}
|
||||
// returns the first node in this Deque where the predicate returns true
|
||||
// if nothing is found return header
|
||||
ANode<T> find(IPred<T> p) {
|
||||
// start at first node so when we hit sentinel we return sentinel
|
||||
return this.header.next.find(p);
|
||||
}
|
||||
// removes the given node from this Deque
|
||||
// If the given node is the Sentinel header, the method does nothing
|
||||
void removeNode(Node<T> n) {
|
||||
ANode<T> found = this.find(new MatchToData<T>(n.data));
|
||||
// we dont want to remove the sentinel node
|
||||
if (found instanceof Sentinel) {
|
||||
return;
|
||||
}
|
||||
found.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
import tester.Tester;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ListOfLists<T> implements Iterable<T> {
|
||||
ArrayList<ArrayList<T>> contents;
|
||||
ListOfLists(ArrayList<ArrayList<T>> contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
ListOfLists() {
|
||||
this(new ArrayList<ArrayList<T>>());
|
||||
}
|
||||
// adds a new empty ArrayList<T> to the end of the list-of-lists.
|
||||
void addNewList() {
|
||||
this.contents.add(new ArrayList<T>());
|
||||
}
|
||||
// adds the provided object to the end of the ArrayList<T> at the
|
||||
// provided index in teh list-of-lists. If the index is invalid,
|
||||
// this method should throw an IndexOutOfBoundsException with a
|
||||
// suitable message.
|
||||
void add(int index, T object) {
|
||||
this.contents.get(index).add(object);
|
||||
}
|
||||
ArrayList<T> get(int index) {
|
||||
if (index < 0 && index > this.contents.size()) {
|
||||
throw new IndexOutOfBoundsException("Bad Index Value");
|
||||
}
|
||||
return this.contents.get(index);
|
||||
}
|
||||
public int size() {
|
||||
return this.contents.size();
|
||||
}
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new ListIterator<T>(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ListIterator<T> implements Iterator<T> {
|
||||
ListOfLists<T> listofList;
|
||||
Iterator<T> currentSubListIter;
|
||||
int nextIndex;
|
||||
ListIterator(ListOfLists<T> listofList) {
|
||||
this.listofList = listofList;
|
||||
this.nextIndex = 0;
|
||||
this.currentSubListIter = listofList.get(nextIndex).iterator();
|
||||
this.nextIndex++;
|
||||
}
|
||||
public boolean hasNext() {
|
||||
return nextIndex < listofList.size() && currentSubListIter.hasNext();
|
||||
}
|
||||
public T next() {
|
||||
if (!currentSubListIter.hasNext()) {
|
||||
this.currentSubListIter = listofList.get(nextIndex).iterator();
|
||||
this.nextIndex++;
|
||||
}
|
||||
return currentSubListIter.next();
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Remove Action Unsupported.");
|
||||
}
|
||||
}
|
||||
|
||||
class LofLExamples {
|
||||
void testListOfLists(Tester t) {
|
||||
ListOfLists<Integer> lol = new ListOfLists<Integer>();
|
||||
t.checkExpect(lol.contents.size(), 0);
|
||||
//add 3 lists
|
||||
lol.addNewList();
|
||||
lol.addNewList();
|
||||
lol.addNewList();
|
||||
t.checkExpect(lol.contents.size(), 3);
|
||||
|
||||
//add elements 1,2,3 in first list
|
||||
t.checkExpect(lol.contents.get(0).size(), 0);
|
||||
lol.add(0, 1);
|
||||
lol.add(0, 2);
|
||||
lol.add(0, 3);
|
||||
t.checkExpect(lol.contents.get(0).size(), 3);
|
||||
|
||||
//add elements 4,5,6 in second list
|
||||
t.checkExpect(lol.contents.get(1).size(), 0);
|
||||
lol.add(1, 4);
|
||||
lol.add(1, 5);
|
||||
lol.add(1, 6);
|
||||
t.checkExpect(lol.contents.get(1).size(), 3);
|
||||
|
||||
//add elements 7,8,9 in third list
|
||||
t.checkExpect(lol.contents.get(2).size(), 0);
|
||||
lol.add(2, 7);
|
||||
lol.add(2, 8);
|
||||
lol.add(2, 9);
|
||||
t.checkExpect(lol.contents.get(0).size(), 3);
|
||||
|
||||
//iterator should return elements in order 1,2,3,4,5,6,7,8,9
|
||||
int number = 1;
|
||||
for (Integer num : lol) {
|
||||
t.checkExpect(num, number);
|
||||
number = number + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
import java.util.Objects;
|
||||
import tester.Tester;
|
||||
|
||||
class Runner {
|
||||
int age;
|
||||
String name;
|
||||
|
||||
Runner(int age, String name) {
|
||||
this.age = age;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Runner)) {
|
||||
return false;
|
||||
}
|
||||
Runner rObj = (Runner) obj;
|
||||
return this.name.equals(rObj.name) && this.age == rObj.age;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.name, this.age);
|
||||
}
|
||||
}
|
||||
|
||||
class RunnerExamples {
|
||||
Runner amy;
|
||||
Runner bob;
|
||||
Runner cale;
|
||||
Runner dave;
|
||||
Runner stillBob;
|
||||
Runner notBob;
|
||||
void init() {
|
||||
amy = new Runner(50, "amy");
|
||||
bob = new Runner(40, "bob");
|
||||
cale = new Runner(30, "cale");
|
||||
dave = new Runner(20, "dave");
|
||||
|
||||
stillBob = new Runner(40, "bob");
|
||||
notBob = new Runner(20, "bob");
|
||||
}
|
||||
void testHashEquality(Tester t) {
|
||||
init();
|
||||
t.checkExpect(this.bob.equals(this.bob), true);
|
||||
t.checkExpect(this.bob.equals(this.stillBob), true);
|
||||
t.checkExpect(this.bob.equals(this.notBob), false);
|
||||
t.checkExpect(this.bob.hashCode(), this.stillBob.hashCode());
|
||||
t.checkExpect(this.amy.hashCode(), new Runner(50, "amy").hashCode());
|
||||
t.checkExpect(this.bob.hashCode() == this.notBob.hashCode(), false);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
import tester.Tester;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
class Stack<T> {
|
||||
Deque<T> contents;
|
||||
|
||||
Stack(Deque<T> contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
Stack() {
|
||||
this.contents = new Deque<T>();
|
||||
}
|
||||
|
||||
//adds an item to the stack
|
||||
void push(T item) {
|
||||
this.contents.addAtHead(new Node<T>(item));
|
||||
}
|
||||
// returns true if contents are empty
|
||||
boolean isEmpty() {
|
||||
if (contents.size() == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//removes and returns the top of the stack
|
||||
T pop() {
|
||||
return this.contents.removeFromHead().getData();
|
||||
}
|
||||
}
|
||||
|
||||
class Utils {
|
||||
// Using loops and one or more stacks, define the method that reverses an ArrayList:
|
||||
<T> ArrayList<T> reverse(ArrayList<T> source) {
|
||||
ArrayList<T> response = new ArrayList<T>();
|
||||
Stack<T> intermediate = new Stack<T>();
|
||||
int size = 0;
|
||||
for (T item : source) {
|
||||
intermediate.push(item);
|
||||
size++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
response.add(i, intermediate.pop());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
class StackExamples {
|
||||
Stack<Runner> s0;
|
||||
Stack<Runner> s1;
|
||||
Deque<Runner> dqAns;
|
||||
|
||||
Runner amy;
|
||||
Runner bob;
|
||||
Runner cale;
|
||||
Runner dave;
|
||||
Runner stillBob;
|
||||
Runner notBob;
|
||||
void init() {
|
||||
amy = new Runner(50, "amy");
|
||||
bob = new Runner(40, "bob");
|
||||
cale = new Runner(30, "cale");
|
||||
dave = new Runner(20, "dave");
|
||||
stillBob = new Runner(40, "bob");
|
||||
notBob = new Runner(20, "bob");
|
||||
|
||||
s0 = new Stack<Runner>();
|
||||
s1 = new Stack<Runner>();
|
||||
dqAns = new Deque<Runner>();
|
||||
}
|
||||
void testPush(Tester t) {
|
||||
init();
|
||||
t.checkExpect(s1.contents.header.next, s1.contents.header);
|
||||
s1.push(dave);
|
||||
t.checkExpect(s1.contents.header.next,
|
||||
new Node<Runner>(dave, dqAns.header, dqAns.header));
|
||||
s1.push(cale);
|
||||
t.checkExpect(s1.contents.header.next,
|
||||
new Node<Runner>(cale, dqAns.header, dqAns.header.prev));
|
||||
}
|
||||
void testIsEmpty(Tester t) {
|
||||
init();
|
||||
t.checkExpect(s0.isEmpty(), true);
|
||||
t.checkExpect(s1.isEmpty(), true);
|
||||
s1.push(dave);
|
||||
t.checkExpect(s1.isEmpty(), false);
|
||||
}
|
||||
void testPop(Tester t) {
|
||||
init();
|
||||
t.checkException(
|
||||
new RuntimeException("Cannot remove item from empty list"),
|
||||
s1,
|
||||
"pop");
|
||||
s1.push(dave);
|
||||
t.checkExpect(s1.pop(), dave);
|
||||
s1.push(dave);
|
||||
s1.push(cale);
|
||||
s1.push(bob);
|
||||
s1.push(amy);
|
||||
t.checkExpect(s1.pop(), amy);
|
||||
t.checkExpect(s1.pop(), bob);
|
||||
t.checkExpect(s1.pop(), cale);
|
||||
t.checkExpect(s1.pop(), dave);
|
||||
}
|
||||
void testReverseArrayList(Tester t) {
|
||||
ArrayList<Runner> fwd = new ArrayList<Runner>(Arrays.asList(amy, bob, cale, dave));
|
||||
ArrayList<Runner> rev = new ArrayList<Runner>(Arrays.asList(dave, cale, bob, amy));
|
||||
t.checkExpect(new Utils().reverse(fwd), rev);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
import tester.Tester;
|
||||
|
||||
class StringCreator {
|
||||
String contents;
|
||||
Stack<String> actions;
|
||||
StringCreator() {
|
||||
contents = "";
|
||||
actions = new Stack<String>();
|
||||
}
|
||||
|
||||
String getString() {
|
||||
return contents;
|
||||
}
|
||||
void add(char item) {
|
||||
this.actions.push(this.contents);
|
||||
this.contents = this.contents + item;
|
||||
}
|
||||
void remove() {
|
||||
this.actions.push(this.contents);
|
||||
this.contents = this.contents.substring(0, this.contents.length() - 1);
|
||||
}
|
||||
void undo() {
|
||||
if (!this.actions.isEmpty()) {
|
||||
this.contents = this.actions.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class StringExamples {
|
||||
void testRun(Tester t) {
|
||||
StringCreator creator = new StringCreator();
|
||||
t.checkExpect(creator.getString(), "");
|
||||
creator.add('c');
|
||||
creator.add('d');
|
||||
t.checkExpect(creator.getString(), "cd");
|
||||
creator.add('e');
|
||||
t.checkExpect(creator.getString(), "cde");
|
||||
creator.remove();
|
||||
creator.remove();
|
||||
t.checkExpect(creator.getString(), "c");
|
||||
creator.undo(); //undoes the removal of 'd'
|
||||
t.checkExpect(creator.getString(), "cd");
|
||||
creator.undo(); //undoes the removal of 'e'
|
||||
creator.undo(); //undoes the addition of 'e'
|
||||
t.checkExpect(creator.getString(), "cd");
|
||||
creator.add('a');
|
||||
t.checkExpect(creator.getString(), "cda");
|
||||
creator.undo(); //undoes the addition of 'a'
|
||||
creator.undo(); //undoes the addition of 'd'
|
||||
creator.undo(); //undoes the addition of 'c'
|
||||
t.checkExpect(creator.getString(), "");
|
||||
creator.undo(); //no effect, there is nothing to undo
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user