diff --git a/.idea/misc.xml b/.idea/misc.xml index 07115cd..05b1176 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 3e59c38..a8155b2 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,71 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.SeparateChainingHashSet; + +import java.util.Scanner; + public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + String inputString = "S E A R C H E X A M P L E"; + String inputStringTwo = "F A K E E X A M P L E"; + + Scanner input = new Scanner(inputString); + Scanner inputTwo = new Scanner(inputStringTwo); + + MathSet ms = new SeparateChainingHashSet(997); + MathSet otherMS = new SeparateChainingHashSet<>(997); + //MathSet ms = new BSTSet<>(); + //MathSet otherMS = new BSTSet<>(); + + // isEmpty test before adding anything + System.out.println(ms.isEmpty()); + + // add method tests + while(input.hasNext()) { + String key = input.next(); + ms.add(key); + } + while(inputTwo.hasNext()) { + String key = inputTwo.next(); + otherMS.add(key); + } + System.out.println(); + + // isEmpty test after adding + System.out.println(ms.isEmpty()); + System.out.println(); + + // keys tests + for (String s : ms.keys()) { + System.out.println(s); + } + System.out.println(); + + //contains tests + System.out.println("Contains S: " + ms.contains("S")); + System.out.println("Contains Y: " + ms.contains("Y")); + System.out.println(); + + // union intersect and difference tests + MathSet union = ms.union(otherMS); + System.out.println("union"); + for (String s : union.keys()) { + System.out.println(s); + } + System.out.println(); + + MathSet intersect = ms.intersection(otherMS); + System.out.println("intersection"); + for (String s : intersect.keys()) { + System.out.println(s); + } + System.out.println(); + + MathSet diff = ms.difference(otherMS); + System.out.println("difference"); + for (String s : diff.keys()) { + System.out.println(s); + } + System.out.println(); } } \ 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..214b127 --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,145 @@ +package edu.greenriver.sdev333; + +import java.util.Comparator; +import java.util.Iterator; + +public class BSTSet> implements MathSet { + + // node helper class + 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; + } + } + + // field + private Node root; + + @Override + public void add(KeyType key) { + root = add(root, key); + } + + private Node add (Node current, KeyType key) { + // Current is the root of the subtree we are looking at + + //where we want to be + if (current == null) { + return new Node(key, 1); + } + int cmp = key.compareTo(current.key); + if (cmp < 0) { + // go left + current.left = add(current.left, key); + }else if (cmp > 0) { + // go right + current.right = add(current.right, key); + } else { + current.key = key; + } + + current.N = size(current.left) + size(current.right) + 1; + return current; + } + + + @Override + public boolean contains(KeyType key) { + Node current = root; + while (current != null) { + int cmp = key.compareTo(current.key); + if (cmp < 0) { + // go left + current = current.left; + } else if (cmp > 0) { + // go right + current = current.right; + } else { + // match found, return true; + return true; + } + }// no match was found if we get here + return false; + } + + @Override + public boolean isEmpty() { + return size(root) == 0; + } + + @Override + public int size() { + return size(root); + } + + // private helper method for size, traverses the tree to record the size + private int size(Node current) { + if (current == null) { + return 0; + }else { + return size(current.left) + size(current.right) + 1; + } + } + + @Override + public MathSet union(MathSet other) { + MathSet intersections = new BSTSet(); + + for (KeyType currentKey : this.keys()) { + intersections.add(currentKey); + } + for (KeyType currentKey : other.keys()) { + intersections.add(currentKey); + } + return intersections; + } + + @Override + public MathSet intersection(MathSet other) { + MathSet intersections = new BSTSet(); + + for (KeyType currentKey : this.keys()) { + if (this.contains(currentKey) && other.contains(currentKey)) { + intersections.add(currentKey); + } + } + return intersections; + } + + @Override + public MathSet difference(MathSet other) { + MathSet differences = new BSTSet<>(); + + for (KeyType key : this.keys()) { + if (!other.contains(key)) { + differences.add(key); + } + } + + return differences; + } + + @Override + public Iterable keys() { + Queue keys = new Queue<>(); + inorder(root, keys); + + return keys; + } + + private void inorder(Node current, Queue q) { + if (current == null) { + // do nothing - intentionally blank + return; + } + inorder(current.left, q); + q.enqueue(current.key); + inorder(current.right, q); + } +} diff --git a/src/edu/greenriver/sdev333/MathSet.java b/src/edu/greenriver/sdev333/MathSet.java index 4273aba..51bdd2d 100644 --- a/src/edu/greenriver/sdev333/MathSet.java +++ b/src/edu/greenriver/sdev333/MathSet.java @@ -1,5 +1,9 @@ package edu.greenriver.sdev333; +/** + * Stewart Lovell + */ + /** * A MathSet represents a finite mathematical set. * Sets have a collection of unique elements (keys) - no duplicate keys allowed. diff --git a/src/edu/greenriver/sdev333/SeparateChainingHashSet.java b/src/edu/greenriver/sdev333/SeparateChainingHashSet.java new file mode 100644 index 0000000..8f751ba --- /dev/null +++ b/src/edu/greenriver/sdev333/SeparateChainingHashSet.java @@ -0,0 +1,93 @@ +package edu.greenriver.sdev333; + +public class SeparateChainingHashSet implements MathSet { + // fields: + // array of linked lists + int m; + private SequentialSearchSet[] st; + + public SeparateChainingHashSet(int m) { + this.m = m; + st = (SequentialSearchSet[]) new SequentialSearchSet[m]; + for (int i = 0; i < m; i++) { + st[i] = new SequentialSearchSet(); + } + } + + private int hash(KeyType key) { + return (key.hashCode() & 0x7fffffff) % m; + } + + @Override + public void add(KeyType key) { + st[hash(key)].put(key); + } + + @Override + public boolean contains(KeyType key) { + return st[hash(key)].get(key) != null; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + int size = 0; + for (SequentialSearchSet set : st) { + size+= set.size(); + } + return size; + } + + @Override + public MathSet union(MathSet other) { + MathSet union = new SeparateChainingHashSet<>(m); + + for (KeyType currentKey : this.keys()) { + union.add(currentKey); + } + for (KeyType currentKey : other.keys()) { + union.add(currentKey); + } + return union; + } + + @Override + public MathSet intersection(MathSet other) { + MathSet intersection = new SeparateChainingHashSet<>(m); + + for (KeyType currentKey : this.keys()) { + if (this.contains(currentKey) && other.contains(currentKey)) { + intersection.add(currentKey); + } + } + return intersection; + } + + @Override + public MathSet difference(MathSet other) { + MathSet difference = new SeparateChainingHashSet<>(m); + + for (KeyType currentKey : this.keys()) { + if (!other.contains(currentKey)) { + difference.add(currentKey); + } + } + return difference; + } + + @Override + public Iterable keys() { + Queue keys = new Queue<>(); + + for(SequentialSearchSet set : st) { + for (KeyType key : set.keys()) { + keys.enqueue(key); + } + } + return keys; + } +} \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/SequentialSearchSet.java b/src/edu/greenriver/sdev333/SequentialSearchSet.java new file mode 100644 index 0000000..49d482c --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchSet.java @@ -0,0 +1,58 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; + +/** + * Sequential search (unordered linked list implementation) of Symbol Table + * Refer to p. 374-377 in Sedgewick and Wayne, Algorithms, 4th edition + * @param + */ + +public class SequentialSearchSet { + + private Node first; + private int size = 0; + + private class Node { + KeyType key; + Node next; + + public Node (KeyType key, Node next) { + this.key = key; + this.next = next; + } + } + public void put(KeyType key) { + for (Node current = first; current != null; current = current.next) { + if (key.equals(current.key)) { + return; + } + } + first = new Node(key, first); + size++; + } + + public KeyType get(KeyType key) { + for (Node current = first; current != null; current = current.next) { + if (key.equals(current.key)) { + return current.key; + } + } + return null; + } + + public int size() { + return size; + } + + public Iterable keys() { + Queue keys = new Queue<>(); + + Node current = first; + while(current != null) { + keys.enqueue(current.key); + current = current.next; + } + return keys; + } +} \ No newline at end of file