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..41f7f20 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,100 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.SeperateChainingHashTableSet; + +import java.util.Scanner; + public class Main { public static void main(String[] args) { + + /// okay both implementations work ken, just uncommen the one you want to use System.out.println("Hello world!"); + + //string created to put in set + String testString = "A E S T H E T I C "; + + //tester method + //MathSet tester = new BSTSet(); + MathSet tester = new SeperateChainingHashTableSet<>(); + + + //scanner to add string to BSTSet + Scanner input = new Scanner(testString); + + //testing is empty before anything is added + System.out.println(tester.isEmpty()); + + //loop to add the strings as keys to my tester + while(input.hasNext()){ + String key = input.next(); + tester.add(key); + } + + //MathSet otherTester = new BSTSet(); + MathSet otherTester = new SeperateChainingHashTableSet<>(); + otherTester.add("A"); + otherTester.add("a"); + otherTester.add("e"); + otherTester.add("E"); + otherTester.add("P"); + otherTester.add("T"); + otherTester.add("O"); + otherTester.add("P"); + otherTester.add(("i")); + + //testing all my methods + System.out.println(tester.size()); + System.out.println(tester.contains("A")); + System.out.println(tester.contains("T")); + System.out.println(tester.contains("t")); + System.out.println(tester.contains("p")); + System.out.println(tester.isEmpty()); + System.out.println(); + + System.out.println("//////////////////////////////////////////////"); + + System.out.println(); + // and again on otherTester + System.out.println(otherTester.size()); + System.out.println(otherTester.contains("A")); + System.out.println(otherTester.contains("T")); + System.out.println(otherTester.contains("t")); + System.out.println(otherTester.contains("p")); + System.out.println(otherTester.isEmpty()); + System.out.println(); + + System.out.println("//////////////////////////////////////////////"); + + System.out.println(); + // this is the tester for the 3 set specific methods + MathSet unionTester = tester.union(otherTester); + System.out.println("union of tester and otherTester"); + for (String element: unionTester.keys()){ + System.out.println(element); + } + System.out.println(); + System.out.println("//////////////////////////////////////////////"); + System.out.println(); + + System.out.println("intersection of tester and otherTester"); + MathSet intersectionTester = tester.intersection((otherTester)); + for (String element: intersectionTester.keys()){ + System.out.println(element); + } + + System.out.println(); + System.out.println("//////////////////////////////////////////////"); + System.out.println(); + + System.out.println("difference of tester and otherTester"); + MathSet differenceTester = tester.difference((otherTester)); + for (String element: differenceTester.keys()){ + System.out.println(element); + } + + + + + } } \ 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..365adb7 --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,226 @@ +package edu.greenriver.sdev333; +import java.util.*; +public class BSTSet> implements MathSet{ + + private Node root; + + + //helper class + private class Node { + private KeyType key; + + private Node left; + private Node right; + private int N; // Number of Nodes in the subtree rooted here + + public Node(KeyType key, int N){ + this.key = key; + this.N = N; + } + + } + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @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 are supposed to be + if (current == null) { + return new Node(key, 1); + } + + int cmp = key.compareTo(current.key); + // cmp will be -1(negative) if key < current.key + //cmp will be 0(zero) if the key == current.key + // cmp will be +1(positive) if key > 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 { + //key already exists + current.key = key; + } + + current.N = size(current.left) + size(current.right) + 1; + + return current; + + } + + @Override + public int size() { + return size(root); + } + + private int size(Node current){ + if(current == null){ + return 0; + } else { + return size(current.left) + size(current.right) + 1; + } + } + + /** + * 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) { + + + //if someone gives me a key, i want to find the value for that key + Node current = root; + while(current != null){ + int cmp = key.compareTo(current.key); + //compareTo returns neg, zero, pos + + if(cmp < 0){ + current = current.left; + }else if(cmp > 0){ + current = current.right; + }else { + return true; + } + }// end of the while loop + + return false; + } + + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return root == null || root.N == 0; + } + + + + /** + * 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) { + MathSet result = new BSTSet(); + + //add all the elements of this se to the result set + for(KeyType currentKey : this.keys()){ + result.add(currentKey); + } + + // add elements of the other set to the result set if they are not already in the result set + 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 a result + MathSet result = new BSTSet(); + + for(KeyType currentKey : this.keys()){ + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + + return result; + + + + //iterator version +// //iterate(walk through) all items in 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 + */ + public Iterable keys() { + Queue queue = new Queue<>(); + //start the recursion, collecting the results in the queue + inorder(root,queue); + //when done, return the queue + return queue; + } + + 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..070f96d 100644 --- a/src/edu/greenriver/sdev333/MathSet.java +++ b/src/edu/greenriver/sdev333/MathSet.java @@ -1,6 +1,8 @@ package edu.greenriver.sdev333; /** + * @author Adam Wise + * * A MathSet represents a finite mathematical set. * Sets have a collection of unique elements (keys) - no duplicate keys allowed. * Set operations include contains, size, union, intersection, and difference. diff --git a/src/edu/greenriver/sdev333/SeperateChainingHashTableSet.java b/src/edu/greenriver/sdev333/SeperateChainingHashTableSet.java new file mode 100644 index 0000000..d310559 --- /dev/null +++ b/src/edu/greenriver/sdev333/SeperateChainingHashTableSet.java @@ -0,0 +1,204 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class SeperateChainingHashTableSet implements MathSet { + + + private Node head; // first node in the linked list + private int size; // size variable for tracking size + + private class Node { + KeyType key; + Node next; + + /** + * Node class used in lunkedlist symbol table implentation + * @param key + * @param next + */ + public Node(KeyType key, Node next) { + this.key = key; + this.next = next; + } + + } + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + + for (Node current = head; current != null; current = current.next) { + if (key.equals(current.key)) { + return; + } + } + head = new Node(key, head); + + } + + + /** + * 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 (Node current = head; current != null; current = current.next) { + if (key.equals(current.key)) { + return true; + } + } + return false; + } + + + /** + * 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() { + for (KeyType key : this.keys()) { + size++; + } + return size; + } + + /** + * 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) { + MathSet result = new SeperateChainingHashTableSet(); + + //add all the elements of this se to the result set + for(KeyType currentKey : this.keys()){ + result.add(currentKey); + } + + // add elements of the other set to the result set if they are not already in the result set + 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 SeperateChainingHashTableSet(); + + 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 a result + MathSet result = new SeperateChainingHashTableSet(); + + for(KeyType currentKey : this.keys()){ + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + + return result; + } + + /** + * 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 SSIterator(head); + } + }; + } + + + /** + * helper iterator class used in for each loops + */ + public class SSIterator implements Iterator { + + private Node current; + + public SSIterator(Node head) { + current = head; + } + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public KeyType next() { + + if (!hasNext()) { + throw new NoSuchElementException(); + } + KeyType key = current.key; + current = current.next; + return key; + } + } +}