diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 3e59c38..7d8c1ba 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,121 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.SCHSet; + public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + + //Test set this + MathSet testSetThis = new BSTSet(); + testSetThis.add(5); + testSetThis.add(8); + testSetThis.add(34); + testSetThis.add(45); + testSetThis.add(13); + testSetThis.add(76); + testSetThis.add(23); + testSetThis.add(2); + testSetThis.add(55); + testSetThis.add(31); + + //Test set other + MathSet testSetOther = new BSTSet(); + testSetOther.add(5); + testSetOther.add(8); + testSetOther.add(34); + testSetOther.add(89); + testSetOther.add(13); + testSetOther.add(76); + testSetOther.add(29); + testSetOther.add(2); + testSetOther.add(25); + testSetOther.add(39); + + //Test Union + MathSet testSetUnion = testSetThis.union(testSetOther); + + for (Integer currentKey: testSetUnion.keys() + ) { + System.out.print("BST Union: " + currentKey); + System.out.print("\n"); + } + + //Test Difference + MathSet testSetDifference = testSetThis.difference(testSetOther); + + for (Integer currentKey: testSetDifference.keys() + ) { + System.out.print("BST Difference: " + currentKey); + System.out.print("\n"); + } + + //Test Intersection + MathSet testSetIntersection = testSetThis.intersection(testSetOther); + + for (Integer currentKey: testSetIntersection.keys() + ) { + System.out.print("BST Intersection: " + currentKey); + System.out.print("\n"); + } + +// SCH TEST + + //Test set this + MathSet testSetThisChain = new SCHSet(); + testSetThisChain.add(5); + testSetThisChain.add(8); + testSetThisChain.add(34); + testSetThisChain.add(45); + testSetThisChain.add(13); + testSetThisChain.add(76); + testSetThisChain.add(23); + testSetThisChain.add(2); + testSetThisChain.add(55); + testSetThisChain.add(31); + + //Test set other + MathSet testSetOtherChain = new SCHSet(); + testSetOtherChain.add(5); + testSetOtherChain.add(8); + testSetOtherChain.add(34); + testSetOtherChain.add(89); + testSetOtherChain.add(13); + testSetOtherChain.add(76); + testSetOtherChain.add(29); + testSetOtherChain.add(2); + testSetOtherChain.add(25); + testSetOtherChain.add(39); + + //Test Union + MathSet testSetUnionChain = testSetThisChain.union(testSetOtherChain); + + for (Integer currentKey: testSetUnionChain.keys() + ) { + System.out.print("SCH Union: " + currentKey); + System.out.print("\n"); + } + + //Test Difference + MathSet testSetDifferenceChain = testSetThisChain.difference(testSetOtherChain); + + for (Integer currentKey: testSetDifferenceChain.keys() + ) { + System.out.print("SCH Difference: " + currentKey); + System.out.print("\n"); + } + + //Test Inersection + MathSet testSetIntersectionChain = testSetThisChain.intersection(testSetOtherChain); + + for (Integer currentKey: testSetIntersectionChain.keys() + ) { + System.out.print("SCH Intersection: " + currentKey); + System.out.print("\n"); + } + + System.out.println(testSetThis.isEmpty()); + System.out.println(testSetThisChain.isEmpty()); + System.out.println(testSetThis.contains(13)); + System.out.println(testSetOtherChain.contains(98)); } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/BSTSet.java b/src/edu/greenriver/sdev333/BSTSet.java new file mode 100644 index 0000000..ff09f27 --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,229 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; + +public class BSTSet> implements MathSet{ + private class Node { + private KeyType key; + private Node left; + private Node right; + private int N; + + public Node(KeyType key, int N){ + this.key = key; + this.N = N; + } + } + + private Node root; + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ +// @Override +// public void add(KeyType key) { +// +// } + @Override + public void add(KeyType key) { + root = put(root, key); + } + + public Node put(Node current, KeyType key){ + //current is null create a new node n = 1 + if(current == null){ + return new Node(key,1); + } + //compare key past in to current key + int cmp = key.compareTo(current.key); + + //if cmp less than 0 then put on left, if greater than 0 put on right else change current val + if (cmp < 0 ) { + current.left = put(current.left, key); + } else if (cmp > 0 ){ + current.right = put(current.right, key); + } + //increment n + current.N = size(current.left) + size(current.right) + 1; + return current; + } + + /** + * Returns the value associated with the given key in the set. + * + * @param key the key to look up + * @return the value associated with the given key, or null if the key is not found in the set + */ + public KeyType get(KeyType key) { + Node node = root; + while (node != null) { + int cmp = key.compareTo(node.key); + if (cmp < 0) { + node = node.left; + } else if (cmp > 0) { + node = node.right; + } else { + return node.key; + } + } + return null; + } + + /** + * Is the key in the set? + * + * @param key key to check + * @return true if key is in the set, false otherwise + */ + @Override + public boolean contains(KeyType key) { + + for (KeyType currentKey : this.keys()) { + if(currentKey == key){ + return true; + } + } + return false; + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + if(root.N == 0){ + return true; + } + return false; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + if (root == null){ + return 0; + } else { + return root.N; + } + } + + private int size(Node current) { + if (current == null){ + return 0; + } else { + return current.N; + } + } + + /** + * Determine the union of this set with another specified set. + * Returns A union B, where A is this set, B is other set. + * A union B = {key | A.contains(key) OR B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to union + * @return the union of this set with other + */ + @Override + public MathSet union(MathSet other) { + //create an empty set that will hold the result + MathSet result = new BSTSet(); + + + for (KeyType currentKey: this.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + + for (KeyType currentKey: other.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the intersection of this set with another specified set. + * Returns A intersect B, where A is this set, B is other set. + * A intersect B = {key | A.contains(key) AND B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to intersect + * @return the intersection of this set with other + */ + @Override + public MathSet intersection(MathSet other) { + MathSet result = new BSTSet(); + for (KeyType currentKey : this.keys()) { + if (other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the difference of this set with another specified set. + * Returns A difference B, where A is this set, B is other set. + * A difference B = {key | A.contains(key) AND !B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to difference + * @return the difference of this set with other + */ + @Override + public MathSet difference(MathSet other) { + //create an empty set that will hold the result + MathSet result = new BSTSet(); + + + for (KeyType currentKey: this.keys()) { + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + //Iterate through all of this +// Iterator itr = (Iterator) this.keys(); +// while (itr.hasNext()){ +// KeyType currentKey = itr.next(); +// if (!other.contains(currentKey)) { +// result.add(currentKey); +// } +// } + } + + /** + * Retrieves a collection of all the keys in this set. + * + * @return a collection of all keys in this set + */ + @Override + public Iterable keys() { + Queue queue = new Queue(); + inorder(root, queue); + return new Iterable() { + public Iterator iterator() { + return queue.iterator(); + } + }; + } + + private void inorder(Node current, Queue queue) { + if (current == null) { + return; + } + inorder(current.left, queue); + queue.enqueue(current.key); + inorder(current.right, queue); + } +} diff --git a/src/edu/greenriver/sdev333/Queue.java b/src/edu/greenriver/sdev333/Queue.java index 638d71c..967b987 100644 --- a/src/edu/greenriver/sdev333/Queue.java +++ b/src/edu/greenriver/sdev333/Queue.java @@ -3,6 +3,7 @@ import java.util.Iterator; /** + * @author Thomas Loudon * FIFO queue, page 151 of the red book */ public class Queue implements Iterable { diff --git a/src/edu/greenriver/sdev333/SCHSet.java b/src/edu/greenriver/sdev333/SCHSet.java new file mode 100644 index 0000000..3d34639 --- /dev/null +++ b/src/edu/greenriver/sdev333/SCHSet.java @@ -0,0 +1,196 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +//Bring in sequential search st +public class SCHSet implements MathSet { + private int m; + private SequentialSearchST[] st; + + public SCHSet(){ + this(997); + } + + public SCHSet(int m){ + this.m = m; + //construct an array of SequentialSearchST objects + st = (SequentialSearchST[]) new SequentialSearchST[m]; + //instantiate new Sequential Search objects for each index in the array + for(int i = 0; i < m; i++){ + st[i] = new SequentialSearchST(); + } + } + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + public int hash(KeyType key){ + return (key.hashCode() & 0x7fffffff) % m; + } + @Override + public void add(KeyType key) { + st[hash(key)].add(key); + } + + /** + * Retrieves the value associated with a given key in the set. + * + * @param key the key to retrieve the value for + * @return the value associated with the key, or null if the key is not in the set + */ + public Object get(KeyType key) { + int index = hash(key); + return st[index].get(key); + } + + /** + * Is the key in the set? + * + * @param key key to check + * @return true if key is in the set, false otherwise + */ + @Override + public boolean contains(KeyType key) { + return st[hash(key)].contains(key); + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size() ==0; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + //iterate through array + //at each iteration call st[i].size() add to the size counter + int size = 0; + for(int i=0; i < st.length; i ++){ + size += st[i].size(); + } + return size; + } + + @Override + public MathSet union(MathSet other) { + //create an empty set that will hold the result + MathSet result = new SCHSet(); + + + for (KeyType currentKey: this.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + + for (KeyType currentKey: other.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the intersection of this set with another specified set. + * Returns A intersect B, where A is this set, B is other set. + * A intersect B = {key | A.contains(key) AND B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to intersect + * @return the intersection of this set with other + */ + @Override + public MathSet intersection(MathSet other) { + MathSet result = new SCHSet(); + for (KeyType currentKey : this.keys()) { + if (other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the difference of this set with another specified set. + * Returns A difference B, where A is this set, B is other set. + * A difference B = {key | A.contains(key) AND !B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to difference + * @return the difference of this set with other + */ + @Override + public MathSet difference(MathSet other) { + //create an empty set that will hold the result + MathSet result = new SCHSet(); + + + for (KeyType currentKey: this.keys()) { + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + //Iterate through all of this +// Iterator itr = (Iterator) this.keys(); +// while (itr.hasNext()){ +// KeyType currentKey = itr.next(); +// if (!other.contains(currentKey)) { +// result.add(currentKey); +// } +// } + } + + /** + * Retrieves a collection of all the keys in this set. + * + * @return a collection of all keys in this set + */ + @Override + public Iterable keys() { + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private int currentIndex = 0; + private Iterator currentIterator = st[currentIndex].keys().iterator(); + + @Override + public boolean hasNext() { + while (!currentIterator.hasNext() && currentIndex < m - 1) { + currentIndex++; + currentIterator = st[currentIndex].keys().iterator(); + } + return currentIterator.hasNext(); + } + + @Override + public KeyType next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return currentIterator.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } +} diff --git a/src/edu/greenriver/sdev333/SequentialSearchST.java b/src/edu/greenriver/sdev333/SequentialSearchST.java new file mode 100644 index 0000000..bfa4978 --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchST.java @@ -0,0 +1,203 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Sequential search (unordered linked list implementation) of Symbol Table + * Refer to p. 374-377 in Sedgewick and Wayne, Algorithms, 4th edition + * @param + */ + +public class SequentialSearchST implements MathSet { + public Node first; //also referred to as the root + private int size = 0; + + /** + * Helper Class for LinkedList type implementation + */ + private class Node { + KeyType key; + Node next; + public Node(KeyType key, Node next ){ + this.key = key; + this.next = next; + } + } + + /** + * searches for given key and then puts a value at given key + * @param key + */ + @Override + public void add(KeyType key) { + //if current(first) is not null then loop through and find the key then change the value + for (Node current = first; current != null; current = current.next) { + if (key.equals(current.key)) { + return; + } + } + //thia only runs if first is null + first = new Node(key, first); + } + + public Node get(KeyType key) { + for (Node current = first; current != null; current = current.next) { + if (key.equals(current.key)) { + return current; // return the node with matching key + } + } + return null; // key not found in the set + } + + /** + * Checks if key exists in the set + * @param key + * @return boolean True- contains / False - Does not contain + */ + public boolean contains(KeyType key) { + //start at first/root, while current != null, increment current = current.next + for (Node current = first; current != null; current = current.next){ + //check if current key is equal to the key that we are passing in + if (key.equals(current.key)) { + return true; // the key is present in the set + } + } + return false; // the key is not present in the set + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns the size of the set + * @return size + */ + @Override + public int size() { + for (KeyType s : this.keys()) { + size++; + } + return size; + } + + @Override + public MathSet union(MathSet other) { + //create an empty set that will hold the result + MathSet result = new SequentialSearchST(); + + + for (KeyType currentKey: this.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + + for (KeyType currentKey: other.keys()) { + if(!result.contains(currentKey)) { + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the intersection of this set with another specified set. + * Returns A intersect B, where A is this set, B is other set. + * A intersect B = {key | A.contains(key) AND B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to intersect + * @return the intersection of this set with other + */ + @Override + public MathSet intersection(MathSet other) { + MathSet result = new SequentialSearchST(); + for (KeyType currentKey : this.keys()) { + if (other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the difference of this set with another specified set. + * Returns A difference B, where A is this set, B is other set. + * A difference B = {key | A.contains(key) AND !B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to difference + * @return the difference of this set with other + */ + @Override + public MathSet difference(MathSet other) { + //create an empty set that will hold the result + MathSet result = new SequentialSearchST(); + + + for (KeyType currentKey: this.keys()) { + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + //Iterate through all of this +// Iterator itr = (Iterator) this.keys(); +// while (itr.hasNext()){ +// KeyType currentKey = itr.next(); +// if (!other.contains(currentKey)) { +// result.add(currentKey); +// } +// } + } + + /** + *Returns the keys in order using the helper class SequentialSearchSTKeyIterator + * @return SequentialSearchSTKeyIterator + */ + @Override + public Iterable keys() { + return new Iterable() { + @Override + public Iterator iterator() { + return new SequentialSearchSTKeyIterator(first); + } + }; + } + + /** + * Iterator for the SequentialSearchSymbolTable + */ + public class SequentialSearchSTKeyIterator implements Iterator { + + private Node current; + + public SequentialSearchSTKeyIterator(Node first) { + current = first; + } + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public KeyType next() { + //next is null/ doesn't exist + if (!hasNext()) { + throw new NoSuchElementException(); + } + KeyType key = current.key; + current = current.next; + return key; + } + } +}