diff --git a/.gitignore b/.gitignore index 2362736..fbe84b6 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ hs_err_pid* /Lab109/build/ /Lab110-VenbergGE/nbproject/private/ /Lab110-VenbergGE/build/ +/Lab111-VenbergGE/build/ diff --git a/Lab111-VenbergGE/src/ASCIITable.java b/Lab111-VenbergGE/src/ASCIITable.java new file mode 100644 index 0000000..4ceff25 --- /dev/null +++ b/Lab111-VenbergGE/src/ASCIITable.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * utility library for nicely formatted ascii tables. + * @author Gabriel Venberg + */ +public class ASCIITable { + + /** + * generates an ASCII table based on a 2d data array. the top level array is an array of rows. + * @param data 2d array containing data to put in table + * @param padding how much padding to put on each side of entries + * @param tableHeader string to put in the table header (may cause problems if extremely long) + * @param columnHeaders array of strings to put at the top of each column. + * @return + */ + public static String render(Object data[][], int padding, String tableHeader, String[] columnHeaders) throws IllegalArgumentException { + int cols = calcNoCols(data); + if(cols!=columnHeaders.length){throw new IllegalArgumentException("must have equal number of column headers as columns!");} + int[] colWidths = calcColumnWidth(cols, data, columnHeaders); + //colWidths does not count padding or the | chars betwwen tables. + int width = sumOfArray(colWidths)+padding*cols*2+(cols-1); + String horizontalSpacer = assembleHorizontalSpacers(colWidths, padding, cols); + /*ok, so each cell will have the colwidth for the data, then padding for padding, + * then a | at the end. (plus 1 at the begginning of the table. + there will be 2 rows for each row of data (horizontal sep) plus a horizontal sep + at the end. + */ + String string = horizontalSpacer+'\n'; + //print table header + string=string+tableHeader(tableHeader, width)+"\n"; + string = string+horizontalSpacer+"\n"; + //print coumn headers + string=string+columnHeaderString(colWidths, padding, columnHeaders)+'\n'; + //got everything set up, build the table row by row. + for(int i=0; i { + // + + //Used for a comparison based on the "natural ordering" + // + // return < 0 if this.a < b + // return 0 if this.a = b + // return > 0 if this.a > b + int compareTo( K b ); + +} + diff --git a/Lab111-VenbergGE/src/Comparator.java b/Lab111-VenbergGE/src/Comparator.java new file mode 100644 index 0000000..9ff8b34 --- /dev/null +++ b/Lab111-VenbergGE/src/Comparator.java @@ -0,0 +1,5 @@ + +public interface Comparator { + + int compare( K a, K b ); +} diff --git a/Lab111-VenbergGE/src/DeptComparator.java b/Lab111-VenbergGE/src/DeptComparator.java new file mode 100644 index 0000000..7305e03 --- /dev/null +++ b/Lab111-VenbergGE/src/DeptComparator.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * + * @author Gabriel Venberg + */ +public class DeptComparator implements Comparator{ + public int compare(Employee a, Employee b){ + return a.getDept()-b.getDept(); + } +} diff --git a/Lab111-VenbergGE/src/Employee.java b/Lab111-VenbergGE/src/Employee.java new file mode 100644 index 0000000..9d23619 --- /dev/null +++ b/Lab111-VenbergGE/src/Employee.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * a simple container class for employees. + * @author Gabriel Venberg + */ +public class Employee { + private int SSN; + private String name; + private int dept; + private int hireDate; + + public Employee(int SSN, int dept, int hireDate, String name) throws IllegalArgumentException{ + if(SSN<0||SSN>99999999){throw new IllegalArgumentException("SSN must be between 0 and 99999999");} + if(dept<1||dept>5){throw new IllegalArgumentException("dept must be between 1 and 5");} + if(hireDate<1995||hireDate>2021){throw new IllegalArgumentException("hireDate must be between 1995 and current year.");} + this.SSN=SSN; + this.dept=dept; + this.hireDate=hireDate; + this.name=name; + } + + public int getSSN(){return SSN;} + public int getDept(){return dept;} + public int getHireDate(){return hireDate;} + public String getName(){return name;} + + public void setDept(int dept){ + if(dept<1||dept>5){throw new IllegalArgumentException("dept must be between 1 and 5");} + this.dept=dept; + } + + public void setName(String name){ + this.name=name; + } +} diff --git a/Lab111-VenbergGE/src/HireDateComparator.java b/Lab111-VenbergGE/src/HireDateComparator.java new file mode 100644 index 0000000..664bd3a --- /dev/null +++ b/Lab111-VenbergGE/src/HireDateComparator.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * + * @author Gabriel Venberg + */ +public class HireDateComparator implements Comparator{ + + public int compare(Employee a, Employee b){ + return a.getHireDate()-b.getHireDate(); + } + +} diff --git a/Lab111-VenbergGE/src/IDComparator.java b/Lab111-VenbergGE/src/IDComparator.java new file mode 100644 index 0000000..6fba256 --- /dev/null +++ b/Lab111-VenbergGE/src/IDComparator.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * + * @author Gabriel Venberg + */ +public class IDComparator implements Comparator{ + + public int compare(Employee a, Employee b){ + return a.getSSN()-b.getSSN(); + } + +} diff --git a/Lab111-VenbergGE/src/LinkedQueue.java b/Lab111-VenbergGE/src/LinkedQueue.java new file mode 100644 index 0000000..3140c4b --- /dev/null +++ b/Lab111-VenbergGE/src/LinkedQueue.java @@ -0,0 +1,21 @@ +/* + * Data Structures & Algorithms 6th Edition + * Goodrich, Tamassia, Goldwasser + * Code Fragment 6.11 + * + * An implementation of the LinkedQueue class + * */ + +/** + * + * @author Gabriel Venberg + */ +public class LinkedQueue implements Queue{ + private SinglyLinkedList list = new SinglyLinkedList(); //an empty list + public LinkedQueue(){} //new queue relies on initaly empty list + public int size(){return list.size();} + public boolean isEmpty(){return list.isEmpty();} + public void enqueue(E element){list.addLast(element);} + public E first(){return list.first();} + public E dequeue(){return list.removeFirst();} +} diff --git a/Lab111-VenbergGE/src/NameComparator.java b/Lab111-VenbergGE/src/NameComparator.java new file mode 100644 index 0000000..fe9baa2 --- /dev/null +++ b/Lab111-VenbergGE/src/NameComparator.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * + * @author Gabriel Venberg + */ +public class NameComparator implements Comparator{ + public int compare(Employee a, Employee b){ + return a.getName().compareTo(b.getName()); + } +} diff --git a/Lab111-VenbergGE/src/Queue.java b/Lab111-VenbergGE/src/Queue.java new file mode 100644 index 0000000..0126b36 --- /dev/null +++ b/Lab111-VenbergGE/src/Queue.java @@ -0,0 +1,28 @@ +/** + * Data Structures & Algorithms 6th Edition + * Goodrich, Tamassia, Goldwasser + * Code Fragment 6.9 + * + * An implementation of the Queue interface + * */ + +/** + * + * @author Gabriel Venberg + */ +public interface Queue { + /** returns the number of elements in the queue*/ + int size(); + + /** tests whether the queue is empty*/ + boolean isEmpty(); + + /**inserts an element at the rear of the queue*/ + void enqueue(E e); + + /**returns, but does not remove, the first element of the queue (null if empty). */ + E first(); + + /** removes and returns the first element of the queue (null if empty)*/ + E dequeue(); +} diff --git a/Lab111-VenbergGE/src/SinglyLinkedList.java b/Lab111-VenbergGE/src/SinglyLinkedList.java new file mode 100644 index 0000000..88f25b8 --- /dev/null +++ b/Lab111-VenbergGE/src/SinglyLinkedList.java @@ -0,0 +1,78 @@ +/** + *SinglyLinkedListClass + * Code Fragments 3.14, 3.15 + * from + * Data Structures & Algorithms, 6th edition + * by Michael T. Goodrich, Roberto Tamassia & Michael H. Goldwasser + * Wiley 2014 + * Transcribed by + * @author Gabe Venberg + */ +public class SinglyLinkedList { + + private static class Node { + private E element; //refrence to element stored at this node + private Node next; //refrence to subsequent node of list + + public Node(E e, Node n){ + element = e; + next = n; + } + + public E getElement() {return element;} + + public Node getNext() {return next;} + + public void setNext(Node n) {next = n;} + } + + //instance variables of SinglyLinkedList + private Node head = null;//head node of list + private Node tail = null;//last node of list + private int size = 0;//number of nodes in list + + public SinglyLinkedList(){}//constructs an initaly empty list + + //access methods + public int size() {return size;} + + public boolean isEmpty() {return size == 0;} + + public E first(){//returns but does not remove the first element + if (size == 0) {return null;} //special case + return head.getElement(); + } + + public E last(){//returns but does not remove last elemnt + if (size ==0) {return null;}//special case + return tail.getElement(); + } + + //update methods + public void addFirst(E e){//adds element e to the front of the list + head = new Node<>(e, head);//create and link a new node + if (size == 0) {tail = head;}//special case, head becomes tail also + size++; + } + + public void addLast(E e){//adds element to end of list + Node newest = new Node<>(e, null);//create and link a new node + if(size == 0){//special case, previously empty list + head = newest; + } + else{ + tail.setNext(newest);//new node after existing tail + } + tail = newest;//new node becomes tail + size++; + } + + public E removeFirst(){//removes and returns the first element + if(size == 0){return null;}//nothing to remove + E answer = head.getElement(); + head = head.getNext();//will become null if list had only one node. + size--; + if(size==0){tail = null;}// special case as list is now empty + return answer; + } +} diff --git a/Lab111-VenbergGE/src/Sort.java b/Lab111-VenbergGE/src/Sort.java new file mode 100644 index 0000000..92a0126 --- /dev/null +++ b/Lab111-VenbergGE/src/Sort.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * Class containing a bunch of static sort methods. + * @author Gabriel Venberg + */ +public class Sort { + + /** + * copies an array + * @param type of array + * @param toCopy array to copy + * @return copy of array + */ + public static K[] arrayCopyRange(K[] toCopy, int start, int end){ + K[] output = (K[]) new Object[end-start]; + for(int i=start; i LinkedQueue arrayToQueue(K[] toConvert){ + LinkedQueue output = new LinkedQueue<>(); + for(int i=0; i K[] queueToArray(LinkedQueue toConvert){ + K[] output = (K[]) new Object[toConvert.size()]; + for(int i=0; i type of array + * @param toSort array to sort + * @param comp comparator to use. + */ + public static void badBubbleSort(K[] toSort, Comparator comp){ + //dont want to be constantly creating and destroying this if we dont have to. + K tmp; + for(int i=0; i0){ + //swapping + tmp=toSort[j-1]; + toSort[j-1]=toSort[j]; + toSort[j]=tmp; + } + } + } + } + + /** + * sorts a list in place with an optimized bubble sort. stable + * @param type of array + * @param toSort array to sort + * @param comp comparator to use. + */ + public static void bubbleSort(K[] toSort, Comparator comp){ + K tmp; + int lastSwap; + int sortTo = toSort.length-1; + do{ + //last place we did a swap + lastSwap=0; + //the last place we did a swap is the last place we need to look. + for(int i=1; i0){ + lastSwap=i; + //swapping + tmp=toSort[i-1]; + toSort[i-1]=toSort[i]; + toSort[i]=tmp; + } + } + //so we only compare along the array for as long as we need to. + sortTo=lastSwap; + } while(lastSwap<=1); + } + + /** + * merges the sorted arrays A and B into array C + * @param type of the arrays + * @param A first sorted array + * @param B second sorted array + * @param C array to merge A and B into. + * @param comp comparator to use. + */ + private static void merge(K[] A, K[] B, K[] C, Comparator comp){ + //counters for arrays A and B + int a=0, b=0; + while(a+b type of array + * @param toSort array to sort + * @param comp comparator to use + */ + public static void mergeSort(K[] toSort, Comparator comp){ + //if array is trivially sorted. I think this could be made a bit more space efficent by sorting the array with 1 or 0 swaps when we hit a 2 long array... + if(toSort.length<2){return;} + //devide the arrays. + int mid=toSort.length/2; + K[] A = arrayCopyRange(toSort, 0, mid); + K[] B = arrayCopyRange(toSort, mid, toSort.length); + //recurse + mergeSort(A, comp); + mergeSort(B, comp); + //merge results + merge(A, B, toSort, comp); + } + + /** + * sorts a queue in place with a quicksort. unstable + * @param type of array + * @param toSort array to sort + * @param comp comparator to use + */ + public static void quickSort(Queue toSort, Comparator comp){ + //queue is trivially sorted + if(toSort.size()<2){return;} + //divide + K pivot=toSort.first(); + Queue less = new LinkedQueue<>(); + Queue equal = new LinkedQueue<>(); + Queue greater = new LinkedQueue<>(); + + while(!toSort.isEmpty()){ + K element = toSort.dequeue(); + int c = comp.compare(element, pivot); + if(c<0){less.enqueue(element);} + else if(c>0){greater.enqueue(element);} + else{equal.enqueue(element);} + } + //recurse + quickSort(less, comp); + quickSort(greater, comp); + + //concatenate results + while(!less.isEmpty()){toSort.enqueue(less.dequeue());} + while(!equal.isEmpty()){toSort.enqueue(equal.dequeue());} + while(!greater.isEmpty()){toSort.enqueue(greater.dequeue());} + } + + /** + * sorts an array with a quicksort. unstable + * @param type of array + * @param toSort array to sort + * @param comp comparator to use + */ + public static K[] quickSortArray(K[] toSort, Comparator comp){ + LinkedQueue tmp = arrayToQueue(toSort); + quickSort(tmp, comp); + return queueToArray(tmp); + } + + /** + * sorts an array based on multiple keys, from least + * @param type of array to be sorted + * @param toSort array to sort + * @param comp array of comparators to sort by, with array going from most significant comparator at the start and ending with the least significant comparator. + */ + //in order to keep this generic, we cant use a bucket sort, as we dont have any assumptions about the range of the data. instead, this just applies a series of stable sorts, as described in the textbook and lecture. (latimer didnt get around to explaining the non-naive way to do a radix sort. + public static void radixSort(K[] toSort, Comparator[] comp) throws IllegalArgumentException{ + if(comp.length==0){throw new IllegalArgumentException("must have at least 1 comparator in comp array.");} + + for(int i=comp.length-1; i<=0; i++){ + mergeSort(toSort, comp[i]); + } + } +} diff --git a/Lab111-VenbergGE/src/client.java b/Lab111-VenbergGE/src/client.java new file mode 100644 index 0000000..fe2ea12 --- /dev/null +++ b/Lab111-VenbergGE/src/client.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021 Gabriel Venberg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * + * @author Gabriel Venberg + */ +import java.util.Random; +public class client { + public static void main(String[] args){ + //initalization stuff + Employee[] employees = new Employee[50000]; + long startTime; + long endTime; + String[][] data = new String[4][2]; + Random rgen = new Random(); + Comparator compareName=new NameComparator(); + Comparator compareDept=new DeptComparator(); + Comparator compareID=new IDComparator(); + Comparator compareHireDate=new HireDateComparator(); + Employee[] tmp = new Employee[employees.length]; + + for(int i=0; i K[] arrayCopy(K[] toCopy){ + K[] output = (K[]) new Object[toCopy.length]; + for(int i=0; i