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..3f563a5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,47 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.HashSet; +import edu.greenriver.sdev333.MathSet; + +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 newString = "O T H E R S E T"; + + Scanner input = new Scanner(inputString); + Scanner otherInput = new Scanner(newString); + + //This is currently being used to test HashSet, but can be changed to BSTSet to test that class + MathSet set = new HashSet<>(); + MathSet otherSet = new HashSet<>(); + + while (input.hasNext()) { + String key = input.next(); + set.add(key); + } + + //BST should print out in order A C E H L M P R S X + System.out.println("Set " + set);// Hash: in no particular order: S E A R C H X M P L + + while (otherInput.hasNext()) { + String key = otherInput.next(); + otherSet.add(key); + } + + System.out.println("other Set = " + otherSet);// O T H E R S + + System.out.println(set.contains("E"));//should be true + System.out.println(set.isEmpty());//false as it should be + System.out.println(set.size());//10 + System.out.println(otherSet.isEmpty());//false as it should be + System.out.println(otherSet.size());//6--correct + + //These should print in order for BST, not for Hash but still contain the same letters + System.out.println("intersection " + set.intersection(otherSet));//should be E H R S + System.out.println("union " + set.union(otherSet));// should be A C E H L M O P R S T X + System.out.println("difference " + set.difference(otherSet)); // A C L M P X + System.out.println("other difference " + otherSet.difference(set)); //O T + } } \ 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..1e00908 --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,227 @@ +package edu.greenriver.sdev333; + +/** + * Binary Search Tree Set Class + * + * * Author: Dee Brecke + * * This class uses a binary search tree set to process data and compare two sets + * * using math methods of intersect, union and difference + * * The iterator uses a queue to store data + * + * @param comparable data type to be compared + */ +public class BSTSet> implements MathSet{ + + private Node root; + + private class Node{ + private KeyType key; + private Node left; + private Node right; + private int count; + + public Node(KeyType key, int count){ + this.key = key; + this.count = count; + } + } + + /** + * 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 compare = key.compareTo(current.key); + if(compare < 0){ + current.left = put(current.left, key); + } else if (compare > 0) { + current.right = put(current.right, key); + }else{//this is unnecessary code but a good reminder that if the key is there, no need to do anything + //current.key = key; + //do nothing + } + current.count = 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; + } + + /** + * getter used in other methods to check if a given key is in the set + * @param key + * @return key if it is in the set + */ + public KeyType get(KeyType key) { + return get(root, key); + } + + //private helper method for getter + private KeyType get(Node current, KeyType key){ + if(current==null){ + return null; + } + int compare = key.compareTo(current.key); + if(compare < 0){ + //go left + return get(current.left, key); + }else if(compare > 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); + } + + //helper method + private int size(Node current){ + if(current == null){ + return 0; + }else { + return current.count; + } + } + + /** + * 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(); + //walk through this and put in result + for (KeyType currentKey: this.keys()) { + result.add(currentKey); + } + //then walk through other and put in result + //because it's a set, it won't add duplicates + 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) { + MathSet result = new BSTSet(); + //walk through this and see if they are in other if so put in result + 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) { + MathSet result = new BSTSet(); + //walk through this and see if they are in other if not put in result + 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 + * + * carry over from SymbolTables/BST.java + */ + @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); + } + + /** + * Method to print out results as a string instead of an address + * useful for testing + * @return string version of data in set + */ + public String toString(){ + String output =""; + for(KeyType key: keys()){ + output += key + ", "; + } + return output; + } +} diff --git a/src/edu/greenriver/sdev333/FlightRoutesGraph.java b/src/edu/greenriver/sdev333/FlightRoutesGraph.java new file mode 100644 index 0000000..3830ee0 --- /dev/null +++ b/src/edu/greenriver/sdev333/FlightRoutesGraph.java @@ -0,0 +1,109 @@ +package edu.greenriver.sdev333; + +/** + * Author: Dee Brecke (demoed by Kendrick Hang) + * This class represents a basic graph of airports connected + * by flight paths. + * It is an introductory class which only contains a way to build + * the graph and find the nodes directly connected. We will be + * going into greater depth (or breadth, lol) on this concept next quarter + */ +public class FlightRoutesGraph { + //two sets need to model a graph (network) + //1. a set of vertices (points, nodes) --airports + //2. a set of edges (connections, lines, routes, relationships)--route between airports + + //helper class + private class Edge{ + private String node1; + private String node2; + + public Edge(String from, String to){ + node1 = from; + node2 = to; + } + } + //airports + private MathSet nodes; + //fight paths + private MathSet edges; + + /** + * default constructor + */ + public FlightRoutesGraph(){ + nodes = new BSTSet<>(); //BST okay because strings are comparable + edges = new HashSet<>();//must use hash here because edges are not comparable + } + + /** + * add a node + * @param city airport node + */ + public void addNode(String city){ + nodes.add(city); + } + + /** + * add a route from one city to another + * @param city1 one of the connecting cities + * @param city2 the other connecting city + */ + public void addEdge(String city1, String city2){ + Edge connection = new Edge(city1, city2); + edges.add(connection); + } + + /** + * find all cities that are connected to given city via an edge (flight path) + * @param city airport to check + * @return airports directly connected to airport to check + */ + public MathSet getNeighbors(String city){ + //create an empty set to hold the results + MathSet neighbors = new BSTSet<>(); + //loop through edges and check + //is city either in node1 or node2? + for(Edge e : edges.keys()){ + if (e.node1.equals(city)) { + neighbors.add(e.node2); + } else if (e.node2.equals(city)) { + neighbors.add((e.node1)); + } + } + return neighbors; + } + + //explore graph with BFS--breadth first search + //or with DFS--depth first search (use recursion or stack) + //shortest path algorithm + + /** + * Tester method (to keep Main class clean for testing BSTSet and HashSet only) + * @param args + */ + public static void main(String[] args){ + FlightRoutesGraph g = new FlightRoutesGraph(); + + //add all cities first + g.addNode("JFK"); + g.addNode("ORD"); + g.addNode("ATL"); + g.addNode("MCO"); + g.addNode("SEA"); + g.addNode("DEN"); + + //add connections between cities + g.addEdge("JFK","MCO"); + g.addEdge("ATL","MCO"); + g.addEdge("DEN","ORD"); + g.addEdge("ORD","ATL"); + g.addEdge("SEA","DEN"); + + //look for direct flights from MCO + MathSet directFromMCO = g.getNeighbors("MCO"); + MathSet directFromATL = g.getNeighbors(("ATL")); + System.out.println("Direct flights from MCO: " + directFromMCO); + System.out.println("Direct flights from ATL: " + directFromATL); + } +} diff --git a/src/edu/greenriver/sdev333/HashSet.java b/src/edu/greenriver/sdev333/HashSet.java new file mode 100644 index 0000000..03df2be --- /dev/null +++ b/src/edu/greenriver/sdev333/HashSet.java @@ -0,0 +1,188 @@ +package edu.greenriver.sdev333; + +/** + * Hash Set class + * + * Author: Dee Brecke + * This class uses a hashset to process data and compare two sets + * using math methods of intersect, union and difference + * The constructor uses Sequential Search Set (code borrowed from SequentialSearchST + * from a previoous project) and iterator uses a queue to store data + * @param Any data type to be added to the set + */ +public class HashSet implements MathSet{ + + private SequentialSearchSet[] listArray; //referred to as st in previous project + private int buckets; //referred to as M in previous project and book + + //default constructor + public HashSet(){ + this(1000); + } + + //parameterized constructor (Code from previous project used variables "M" and "st" but I think these are more descriptive + public HashSet(int buckets){ + this.buckets = buckets; + listArray = new SequentialSearchSet[buckets]; + + for(int i = 0; i < buckets; i++){ + listArray[i] = new SequentialSearchSet<>(); + } + } + + private int hash(KeyType key){ + return (key.hashCode() & 0x7fffffff) % buckets; + } + + /** + * 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); + listArray[index].put(key); + } + + /** + * accessor method used in other methods + * @param key item to be checked + * @return item if it is in the set + */ + public KeyType get(KeyType key) { + int index = hash(key); //find array index/bucket + //check in the bucket to see if it's there + return listArray[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 get(key) !=null; + } + + /** + * 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 sum = 0; + for (int i = 0; i < buckets; i++) { + sum+= listArray[i].size(); + } + return sum; + } + + /** + * 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 HashSet(buckets); + //walk through this and put in result + for (KeyType currentKey: this.keys()) { + result.add(currentKey); + } + //then walk through other and put in result + //because it's a set, it won't add duplicates + 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) { + MathSet result = new HashSet(buckets); + //walk through this and see if they are in other if so put in result + 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) { + MathSet result = new HashSet(buckets); + //walk through this and see if they are in other if not put in result + 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() { + Queue collector = new Queue<>(); + for (int i = 0; i < buckets; i++) { + for(KeyType key : listArray[i].keys()){ + collector.enqueue(key); + } + } + return collector; + } + + /** + * Method to print out results as a string instead of an address + * useful for testing + * @return string version of data in set + */ + public String toString(){ + String output =""; + for(KeyType key: keys()){ + output += key + ", "; + } + return output; + } +} diff --git a/src/edu/greenriver/sdev333/MathSet.java b/src/edu/greenriver/sdev333/MathSet.java index 4273aba..e5b24fa 100644 --- a/src/edu/greenriver/sdev333/MathSet.java +++ b/src/edu/greenriver/sdev333/MathSet.java @@ -1,6 +1,8 @@ package edu.greenriver.sdev333; /** + * Dee Brecke + * 3/8/23 * 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/Queue.java b/src/edu/greenriver/sdev333/Queue.java index 638d71c..143e50f 100644 --- a/src/edu/greenriver/sdev333/Queue.java +++ b/src/edu/greenriver/sdev333/Queue.java @@ -3,6 +3,8 @@ import java.util.Iterator; /** + * Dee Brecke + * 3/8/23 * FIFO queue, page 151 of the red book */ public class Queue implements Iterable { diff --git a/src/edu/greenriver/sdev333/SequentialSearchSet.java b/src/edu/greenriver/sdev333/SequentialSearchSet.java new file mode 100644 index 0000000..7fc7549 --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchSet.java @@ -0,0 +1,72 @@ +package edu.greenriver.sdev333; + +public class SequentialSearchSet { + private Node first; //we usually call this head but the book uses first so that's what I did this time + + private int count; + private class Node{ + KeyType key; + Node next; + + /** + * Constructor for Nodes being used int this class + * @param key key + * @param next the next node in the linked list + */ + public Node(KeyType key, Node next){ + this.key = key; + this.next = next; + } + } + + /** + * Given a key value pair, add the node to the structure + * @param key key + */ + 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); + count++; + } + + /** + * Find the value at a given key + * @param key key + * @return value at given key + */ + + public KeyType get(KeyType key) { + for(Node current = first; current !=null; current = current.next){//the book uses x instead of current + if(key.equals(current.key)){ + return current.key; + } + } + return null; + } + + /** + * This method counts how many nodes are in the structure + * @return integer number of nodes in structure + */ + public int size() { + return count; + } + + /** + * iterator to go through the structure and put the nodes into a queue + * @return queue of nodes + */ + + public Iterable keys() { + Queue queue = new Queue<>(); + Node current = first; + while (current !=null){ + queue.enqueue(current.key); + current = current.next; + } + return queue; + } +}