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..fa8a806 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,63 @@ +import edu.greenriver.sdev333.*; + +//Concepts +// +// A set is effectively the same as a map (symbol table) except there are only keys (instead of both keys and values in a map). +// A set does not allow duplicates +// A set is a concept from mathematics: it's a mathematical object. +// Integers are a mathematical object and it consists of a value and allowable operations (add, subtract, multiply, divide, etc.) +// Sets are a mathematical object and it consists of a collection of values (elements or keys) and allowable operations (contains, union, intersection, difference, etc.) +// To Do +// +// Create two classes that implements the MathSet interface, which represents a mathematical set. +// Write some test code in main that tests all of the set operations (perhaps create a MathSet or a MathSet) for both implementations. +// Credit Levels +// +// Full credit if you have: +// One implementation using a Binary Search Tree (BST) or Red Black Balanced Binary Search Tree +// One implementation using a Separate Chaining Hash Table +/*by Alex brenna +* */ public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + + MathSet one = new SeparateChainingHashTable<>(); + System.out.println("Testing SeparateChainingHashTable isEmpty"); + System.out.println(one.isEmpty()); + one.add("1"); + one.add("2"); + one.add("3"); + one.add("5"); + one.add("4"); + System.out.println(one.isEmpty()); + + System.out.println("Testing SeparateChainingHashTable size() "); + System.out.println(one.size()); + + MathSet two = new SeparateChainingHashTable<>(); + two.add("7"); + two.add("5"); + two.add("2"); + two.add("8"); + two.add("1"); + two.add("0"); + System.out.println("Testing SeparateChainingHashTable contains() "); + System.out.println(one.contains("1")); + System.out.println(one.contains("7")); + System.out.println("Testing SeparateChainingHashTable union() "); + MathSet result1 = one.union(two); + for (String a: result1.keys()) { + System.out.println(a); + } + System.out.println("Testing SeparateChainingHashTable intersection() "); + MathSet result2 = one.intersection(two); + for (String a: result2.keys()) { + System.out.println(a); + } + System.out.println("Testing SeparateChainingHashTable difference() "); + MathSet result3 = one.difference(two); + for (String a: result3.keys()) { + System.out.println(a); + } } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/BST.java b/src/edu/greenriver/sdev333/BST.java new file mode 100644 index 0000000..4f1e971 --- /dev/null +++ b/src/edu/greenriver/sdev333/BST.java @@ -0,0 +1,197 @@ +package edu.greenriver.sdev333; +/*by Alex brenna + * */ +public class BST< KeyType extends Comparable> implements MathSet{ + //fields + private Node root;//top of treee + //helper + private class Node{ + private KeyType key; + private Node left; + private Node right; + //number of nodes in the subtree rooted here + private int num; + + public Node(KeyType key, int num){ + this.key = key; + this.num = num; + } + } + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + root = put(root, key); + } + private Node put(Node current, KeyType key) { + if (current == null) { + return new Node(key, 1); + } + int CompareTO = key.compareTo(current.key); + //go left (min/smaller number) + if (CompareTO < 0) { + current.left = put(current.left, key); + } + //go right (bigger/ max number) + else if (CompareTO > 0) { + current.right = put(current.right, key); + } else { + current.key = key; + } + //update N + current.num = size(current.left) + size(current.right) + 1; + return current; + } + /** + * 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 get(key) !=null; + } + //contains helper to clean up code + public KeyType get(KeyType key) { + return get(root,key); + } + //get helper to clean up code + private KeyType get(Node current, KeyType key){ + + if (current == null){ + return null; + } + int cmp = key.compareTo(current.key); + if(cmp < 0){ + return get(current.left, key); + } + else if (cmp > 0) { + return get(current.right, key); + } + else{ + return current.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() { + return size(root); + } + //size helper + private int size(Node current){ + if(current == null){ + return 0; + } + else{ + return current.num; + } + } + /** + * 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 BST<>(); + //all thats in A and B + for (KeyType key : other.keys()) { + result.add(key); + } + for (KeyType key : this.keys()) { + result.add(key); + } + 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) { + //holds result + MathSet result = new BST<>(); + //whats in A and B at same time + for (KeyType key : other.keys()) { + if(this.contains(key)){ + result.add(key); + } + } + 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) { + //holds result + MathSet result = new BST(); + //whats in A but not in B + for (KeyType a: this.keys()) { + if(!other.contains(a)){ + result.add(a); + } + } + 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() { + //empty queue to hold results + Queue queue = new Queue<>(); + //start the recursion collecting results in teh queue + inOrder(root, queue); + return queue; + } + + //helper method for iterator + private void inOrder(Node current, Queue q){ + if(current == null){ + //do nothing -- just exit + return; + } + inOrder(current.left, q); + q.enqueue(current.key); + inOrder(current.right, q); + } +} diff --git a/src/edu/greenriver/sdev333/SeparateChainingHashTable.java b/src/edu/greenriver/sdev333/SeparateChainingHashTable.java new file mode 100644 index 0000000..c8c87f3 --- /dev/null +++ b/src/edu/greenriver/sdev333/SeparateChainingHashTable.java @@ -0,0 +1,167 @@ +package edu.greenriver.sdev333; +import java.security.Key; +import java.util.LinkedList; + +/*by Alex brenna + * */ +public class SeparateChainingHashTable< KeyType extends Comparable> implements MathSet{ + + //fields: + //array of linkedLists + private LinkedList[] st; + //M = number of buckets + private int M; + + public SeparateChainingHashTable(){ + this(997); + + } + + public SeparateChainingHashTable(int M){ + this.M = M; + //create array + st = new LinkedList[M]; + //create linkedList for each position in array + for(int i = 0; i(); + } + + } + private int hash(KeyType key){ + //return int from key provided to get array index to put item in/get item from + return (key.hashCode() & 0x7fffffff) % M; + } + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + int index = hash(key); + //put key/value into bucket + st[index].add(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) { + int index = hash(key); + if(st[index].contains(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() { + int size = 0; + for(int i=0; i < M; i++){ + size += st[i].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 SeparateChainingHashTable<>(); + //all thats in A and B + for (KeyType key : other.keys()) { + result.add(key); + } + for (KeyType key : this.keys()) { + result.add(key); + } + 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) { + //holds result + MathSet result = new SeparateChainingHashTable<>(); + //whats in A and B at same time + for (KeyType key : other.keys()) { + if(this.contains(key)){ + result.add(key); + } + } + 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) { + //holds result + MathSet result = new SeparateChainingHashTable(); + //whats in A but not in B + for (KeyType a: this.keys()) { + if(!other.contains(a)){ + result.add(a); + } + } + 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() { + Queue queue = new Queue<>(); + for(int i =0; i