From a6580a390775d667064d49d44632a07c5849e2e7 Mon Sep 17 00:00:00 2001 From: Dale Kanikkeberg Date: Wed, 8 Mar 2023 14:16:43 -0800 Subject: [PATCH 1/3] Added name to Queue --- src/edu/greenriver/sdev333/Queue.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/edu/greenriver/sdev333/Queue.java b/src/edu/greenriver/sdev333/Queue.java index 638d71c..63948a2 100644 --- a/src/edu/greenriver/sdev333/Queue.java +++ b/src/edu/greenriver/sdev333/Queue.java @@ -3,6 +3,7 @@ import java.util.Iterator; /** + * Dale Kanikkeberg * FIFO queue, page 151 of the red book */ public class Queue implements Iterable { From bd16637b5b1edbb866102e4a8fec55f3974713fe Mon Sep 17 00:00:00 2001 From: Dale Kanikkeberg Date: Tue, 21 Mar 2023 16:47:44 -0700 Subject: [PATCH 2/3] Completed BSTSet and wrote test code in Main --- .idea/vcs.xml | 6 + src/Main.java | 46 +++++ src/edu/greenriver/sdev333/BSTSet.java | 215 ++++++++++++++++++++++++ src/edu/greenriver/sdev333/HashSet.java | 123 ++++++++++++++ 4 files changed, 390 insertions(+) create mode 100644 .idea/vcs.xml create mode 100644 src/edu/greenriver/sdev333/BSTSet.java create mode 100644 src/edu/greenriver/sdev333/HashSet.java 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..64321f9 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,51 @@ +import edu.greenriver.sdev333.*; + public class Main { public static void main(String[] args) { + System.out.println("Hello world!"); + + // Create 2 BSTSets + // add items to each of the sets (some same, some different) + MathSet set1 = new BSTSet<>(); + set1.add("Ken"); + set1.add("Ken"); + set1.add("Tina"); + set1.add("Susan"); + + MathSet set2 = new BSTSet<>(); + set2.add("Josh"); + set2.add("Ken"); + set2.add("Tyler"); + + // Test + + // intersection set 1 and set 2 + MathSet result1 = set1.intersection(set2); + System.out.println("\nBSTSet intersection: "); + for (String key : result1.keys()) { + System.out.println(key); + } + + // union set 1 and set 2 + MathSet result2 = set1.union(set2); + System.out.println("\nBSTSet union: "); + for (String key : result2.keys()) { + System.out.println(key); + } + + // difference set 1 -> set 2 + MathSet result3 = set1.difference(set2); + System.out.println("\nBSTSet difference: "); + for (String key : result3.keys()) { + System.out.println(key); + } + + // difference set 2 -> set 1 + MathSet result4 = set2.difference(set1); + System.out.println("\nBSTSet reverse difference : "); + for (String key : result4.keys()) { + System.out.println(key); + } } } \ 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..981270a --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,215 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class BSTSet> implements MathSet{ + + private Node root; + + public 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); + } + + public Node add(Node x, KeyType key) { + if (x == null) { + return new Node(key, 1); + } + int cmp = key.compareTo(x.key); + if (cmp < 0) x.left = add(x.left, key); + else if (cmp > 0) x.right = add(x.right, key); + x.N = size(x.left) + size(x.right) + 1; + return x; + } + + /** + * 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 contains(root, key); + } + + public boolean contains(Node x, KeyType key) { + if (x == null) { + return false; + } + int cmp = key.compareTo(x.key); + if (cmp < 0) return contains(x.left, key); + else if (cmp > 0) return contains(x.right, key); + else return true; + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return root == null; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + return size(root); + } + + 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(); + + // iterate through all items in this + for (KeyType currentKey : this.keys()) { + // add items that are not in other + if (!other.contains(currentKey)) { + result.add(currentKey); + } + } + // add all items from other + for (KeyType currentKey : other.keys()) { + 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) { + // create an empty set that will hold the result + MathSet result = new BSTSet(); + + // iterate through all items in this + 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(); + + // iterate through all items in this + 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 keys(min(), max()); + } + + public Iterable keys(KeyType lo, KeyType hi) { + Queue queue = new Queue(); + keys(root, queue, lo, hi); + return queue; + } + + private void keys(Node x, Queue queue, KeyType lo, KeyType hi) { + if (x == null) return; + int cmplo = lo.compareTo(x.key); + int cmphi = hi.compareTo(x.key); + if (cmplo < 0) keys(x.left, queue, lo, hi); + if (cmplo <= 0 && cmphi >= 0) queue.enqueue(x.key); + if (cmphi > 0) keys(x.right, queue, lo, hi); + } + + // pulled in min() and max() from BST to help keys() + public KeyType min() { + if (isEmpty()) throw new NoSuchElementException(); + Node x = min(root); + return x.key; + } + + private Node min(Node x) { + if (x.left == null) return x; + return min(x.left); + } + + public KeyType max() { + if (isEmpty()) throw new NoSuchElementException(); + Node x = max(root); + return x.key; + } + + private Node max(Node x) { + if (x.right == null) return x; + return max(x.right); + } +} diff --git a/src/edu/greenriver/sdev333/HashSet.java b/src/edu/greenriver/sdev333/HashSet.java new file mode 100644 index 0000000..bc2455a --- /dev/null +++ b/src/edu/greenriver/sdev333/HashSet.java @@ -0,0 +1,123 @@ +package edu.greenriver.sdev333; + +public class HashSet implements MathSet{ + // fields: + // array of linked lists + //private SequentialSearchST[] st; + private int M; + + public HashSet(int M) { + // take their number of buckets, save it into my field + this.M = M; + + // create new array + //st = new SequentialSearchST[M]; + + // for each bucket, create a linked list + for (int i = 0; i < M; i++) { + // st[i] = new SequentialSearchST<>(); + } + } + + // Used SeparateChainingHastHT as model/example + // ^^^ code manages the "buckets" of the hash table + + // vvv code manages the insides of the buckets of the hash table + // a linked list is inside each bucket + // SeparateChainingHashST depends on having SequentialSearchST + // will need to either bring in SequentialSearchST + // or write your own linked list + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType 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 false; + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return false; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + return 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) { + return null; + } + + /** + * 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) { + return null; + } + + /** + * 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) { + return null; + } + + /** + * Retrieves a collection of all the keys in this set. + * + * @return a collection of all keys in this set + */ + @Override + public Iterable keys() { + return null; + } + +} From 8638ae4ad383b5da2c903b6006948cde24231006 Mon Sep 17 00:00:00 2001 From: Dale Kanikkeberg Date: Wed, 22 Mar 2023 00:32:45 -0700 Subject: [PATCH 3/3] Completed HashSet, updated Main to include testing for it, fixed SequentialSearchSet put() method --- src/Main.java | 51 ++++++++++++- src/edu/greenriver/sdev333/HashSet.java | 75 ++++++++++++++++--- .../sdev333/SequentialSearchSet.java | 53 +++++++++++++ 3 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 src/edu/greenriver/sdev333/SequentialSearchSet.java diff --git a/src/Main.java b/src/Main.java index 64321f9..63f18dc 100644 --- a/src/Main.java +++ b/src/Main.java @@ -5,6 +5,9 @@ public static void main(String[] args) { System.out.println("Hello world!"); + // BSTSET: + System.out.println("\nBSTSet Testing: "); + // Create 2 BSTSets // add items to each of the sets (some same, some different) MathSet set1 = new BSTSet<>(); @@ -43,9 +46,55 @@ public static void main(String[] args) { // difference set 2 -> set 1 MathSet result4 = set2.difference(set1); - System.out.println("\nBSTSet reverse difference : "); + System.out.println("\nBSTSet reverse difference: "); for (String key : result4.keys()) { System.out.println(key); } + + // HASHSET: + System.out.println("\nHashSet Testing: "); + + // Create 2 HashSets + // add items to each of the sets (some same, some different) + MathSet set3 = new HashSet<>(1); + set3.add("Ken"); + set3.add("Ken"); + set3.add("Tina"); + set3.add("Susan"); + + MathSet set4 = new HashSet<>(10); + set4.add("Josh"); + set4.add("Ken"); + set4.add("Tyler"); + + // Test + + // intersection set 3 and set 4 + MathSet result5 = set3.intersection(set4); + System.out.println("\nHashSet intersection: "); + for (String key : result5.keys()) { + System.out.println(key); + } + + // union set 3 and set 4 + MathSet result6 = set3.union(set4); + System.out.println("\nHashSet union: "); + for (String key : result6.keys()) { + System.out.println(key); + } + + // difference set 3 -> set 4 + MathSet result7 = set3.difference(set4); + System.out.println("\nHashSet difference: "); + for (String key : result7.keys()) { + System.out.println(key); + } + + // difference set 4 -> set 3 + MathSet result8 = set4.difference(set3); + System.out.println("\nHashSet reverse difference: "); + for (String key : result8.keys()) { + System.out.println(key); + } } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/HashSet.java b/src/edu/greenriver/sdev333/HashSet.java index bc2455a..d9bb2b2 100644 --- a/src/edu/greenriver/sdev333/HashSet.java +++ b/src/edu/greenriver/sdev333/HashSet.java @@ -3,7 +3,7 @@ public class HashSet implements MathSet{ // fields: // array of linked lists - //private SequentialSearchST[] st; + private SequentialSearchSet[] st; private int M; public HashSet(int M) { @@ -11,11 +11,11 @@ public HashSet(int M) { this.M = M; // create new array - //st = new SequentialSearchST[M]; + st = new SequentialSearchSet[M]; // for each bucket, create a linked list for (int i = 0; i < M; i++) { - // st[i] = new SequentialSearchST<>(); + st[i] = new SequentialSearchSet<>(); } } @@ -27,6 +27,13 @@ public HashSet(int M) { // SeparateChainingHashST depends on having SequentialSearchST // will need to either bring in SequentialSearchST // or write your own linked list + + private int hash(KeyType key) { + // hash function + // given a key, returns an int (bucket #, array index) + return (key.hashCode() & 0x7fffffff) % M; + } + /** * Puts the specified key into the set. * @@ -34,7 +41,8 @@ public HashSet(int M) { */ @Override public void add(KeyType key) { - + int index = hash(key); // find the bucket number + st[index].put(key); } /** @@ -45,7 +53,8 @@ public void add(KeyType key) { */ @Override public boolean contains(KeyType key) { - return false; + int index = hash(key); // find the bucket number + return st[index].contains(key); } /** @@ -55,7 +64,7 @@ public boolean contains(KeyType key) { */ @Override public boolean isEmpty() { - return false; + return size() == 0; } /** @@ -65,7 +74,11 @@ public boolean isEmpty() { */ @Override public int size() { - return 0; + int size = 0; + for (int i = 0; i < M; i++) { + size += st[i].size(); + } + return size; } /** @@ -79,7 +92,21 @@ public int size() { */ @Override public MathSet union(MathSet other) { - return null; + // create an empty set that will hold the result + MathSet result = new HashSet(M); + + // iterate through all items in this + for (KeyType currentKey : this.keys()) { + // add items that are not in other + if (!other.contains(currentKey)) { + result.add(currentKey); + } + } + // add all items from other + for (KeyType currentKey : other.keys()) { + result.add(currentKey); + } + return result; } /** @@ -93,7 +120,17 @@ public MathSet union(MathSet other) { */ @Override public MathSet intersection(MathSet other) { - return null; + // create an empty set that will hold the result + MathSet result = new HashSet(M); + + // iterate through all items in this + for (KeyType currentKey : this.keys()) { + if (other.contains(currentKey)) { + result.add(currentKey); + } + } + + return result; } /** @@ -107,7 +144,17 @@ public MathSet intersection(MathSet other) { */ @Override public MathSet difference(MathSet other) { - return null; + // create an empty set that will hold the result + MathSet result = new HashSet(M); + + // iterate through all items in this + for (KeyType currentKey : this.keys()) { + if (!other.contains(currentKey)) { + result.add(currentKey); + } + } + + return result; } /** @@ -117,7 +164,13 @@ public MathSet difference(MathSet other) { */ @Override public Iterable keys() { - return null; + Queue collector = new Queue<>(); + for (int i = 0; i < M; i++) { + for (KeyType key : st[i].keys()) { + collector.enqueue(key); + } + } + return collector; } } diff --git a/src/edu/greenriver/sdev333/SequentialSearchSet.java b/src/edu/greenriver/sdev333/SequentialSearchSet.java new file mode 100644 index 0000000..9335b43 --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchSet.java @@ -0,0 +1,53 @@ +package edu.greenriver.sdev333; + +/** + * Modification of: + * 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 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 x = first; x != null; x = x.next) { + if (key.equals(x.key)) { + return; + } + } + first = new Node(key, first); + } + + public boolean contains(KeyType key) { + for (Node x = first; x != null; x = x.next) { + if (key.equals(x.key)) return true; + } + return false; + } + + public int size() { + // Have to find size every time, could also keep track as a variable + int size = 0; + for (Node x = first; x != null; x = x.next) { + size++; + } + return size; + } + + public Iterable keys() { + Queue collector = new Queue<>(); + for (Node x = first; x != null; x = x.next) { + collector.enqueue(x.key); + } + return collector; + } +} +