lab 111
This commit is contained in:
parent
b34a4b51aa
commit
a20e689ce8
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -49,3 +49,4 @@ hs_err_pid*
|
|||
/Lab109/build/
|
||||
/Lab110-VenbergGE/nbproject/private/
|
||||
/Lab110-VenbergGE/build/
|
||||
/Lab111-VenbergGE/build/
|
||||
|
|
181
Lab111-VenbergGE/src/ASCIITable.java
Normal file
181
Lab111-VenbergGE/src/ASCIITable.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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<data.length; i++){
|
||||
string = string+horizontalSpacer+"\n";
|
||||
string = string+dataString(colWidths, padding, data[i])+'\n';
|
||||
}
|
||||
string = string+horizontalSpacer;
|
||||
return string;
|
||||
}
|
||||
|
||||
private static String tableHeader(String header, int width){
|
||||
String string="|";
|
||||
int halfPadding=(width-header.length())/2;
|
||||
//front padding
|
||||
for(int i=0; i<halfPadding; i++){string=string+" ";}
|
||||
//if the total padding we need is odd, put it in front of the header
|
||||
if((width-header.length())%2==1){string=string+" ";}
|
||||
string=string+header;
|
||||
//rear padding
|
||||
for(int i=0; i<halfPadding; i++){string=string+" ";}
|
||||
string=string+"|";
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* calcs the sum of all elements in an int array
|
||||
* @param array array to be summed
|
||||
* @return sum of array
|
||||
*/
|
||||
private static int sumOfArray(int[] array){
|
||||
int sum=0;
|
||||
for(int i=0; i<array.length; i++){
|
||||
sum += array[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the maximum number of entries the rows in the data set have
|
||||
* @param data 2D array of data
|
||||
* @return needed number of rows in the final table.
|
||||
*/
|
||||
private static int calcNoCols(Object data[][]){
|
||||
int rows = 0;
|
||||
for(int i=0; i<data.length; i++){
|
||||
rows = Math.max(rows, data[i].length);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the needed column widths for a data array without padding
|
||||
* @param data the array of data
|
||||
* @return an array of integers representing the needed width of each column
|
||||
*/
|
||||
private static int[] calcColumnWidth(int cols, Object data[][], String[] headers){
|
||||
int[] maxWidths = new int[cols];
|
||||
for(int i=0; i<cols; i++){
|
||||
maxWidths[i]=headers[i].length();
|
||||
for(int j=0; j<data.length; j++){
|
||||
maxWidths[i]=Math.max(maxWidths[i], data[j][i].toString().length());
|
||||
}
|
||||
}
|
||||
|
||||
return maxWidths;
|
||||
}
|
||||
|
||||
/**
|
||||
* gives the horizontal spacer needed for the table
|
||||
* @param colWidth width of each column;
|
||||
* @param padding padding on each side of data.
|
||||
* @param noOfCols number of columns;
|
||||
* @return a string suitable to use as the horizontal spacer for the table.
|
||||
*/
|
||||
private static String assembleHorizontalSpacers(int[] colWidth, int padding, int noOfCols){
|
||||
String string = "+";
|
||||
for(int i=0; i<noOfCols; i++){
|
||||
for(int j=0; j<colWidth[i]+2*padding; j++){
|
||||
string = string+'-';
|
||||
}
|
||||
string = string+'+';
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes a single row of the data array and returns a row. Make sure your colWidth is accurate.
|
||||
* @param colWidth width of each column
|
||||
* @param padding min padding to have around each entry
|
||||
* @param data 1D array of data to print
|
||||
* @return a string containing the data
|
||||
*/
|
||||
private static String dataString(int[] colWidth, int padding, Object data[]){
|
||||
String string ="|";
|
||||
//for each entry in the row
|
||||
for(int i=0; i<data.length; i++){
|
||||
//only calc this once.
|
||||
int length=data[i].toString().length();
|
||||
// front padding. Also, I wish java had string multiplication.
|
||||
for(int p=0; p<padding+(colWidth[i]-length); p++){string = string+" ";}
|
||||
string = string+data[i].toString();
|
||||
//rear padding
|
||||
for(int p=0; p<padding; p++){string = string+" ";}
|
||||
string = string+"|";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes an array of strings (column headers) and outputs a single row of the column, center justified.
|
||||
* @param colWidth width of each column
|
||||
* @param padding min padding around each entry
|
||||
* @param columnHeaders 1d array of strings containing col headers
|
||||
* @return
|
||||
*/
|
||||
private static String columnHeaderString(int[] colWidth, int padding, String columnHeaders[]){
|
||||
String string="|";
|
||||
for(int i=0; i<columnHeaders.length; i++){
|
||||
//calc this once.
|
||||
int length=columnHeaders[i].length();
|
||||
int sidePadding=(colWidth[i]-length+padding*2)/2;
|
||||
//front padding
|
||||
for(int p=0; p<sidePadding; p++){string=string+" ";}
|
||||
//if we need an odd number of total padding, add the spare on the front
|
||||
if((colWidth[i]-length)%2==1){string=string+" ";}
|
||||
string=string+columnHeaders[i];
|
||||
//rear padding
|
||||
for(int p=0; p<sidePadding; p++){string=string+" ";}
|
||||
string=string+"|";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
}
|
13
Lab111-VenbergGE/src/Comparable.java
Normal file
13
Lab111-VenbergGE/src/Comparable.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
public interface Comparable <K> {
|
||||
//
|
||||
|
||||
//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 );
|
||||
|
||||
}
|
||||
|
5
Lab111-VenbergGE/src/Comparator.java
Normal file
5
Lab111-VenbergGE/src/Comparator.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
public interface Comparator <K> {
|
||||
|
||||
int compare( K a, K b );
|
||||
}
|
26
Lab111-VenbergGE/src/DeptComparator.java
Normal file
26
Lab111-VenbergGE/src/DeptComparator.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gabriel Venberg
|
||||
*/
|
||||
public class DeptComparator implements Comparator<Employee>{
|
||||
public int compare(Employee a, Employee b){
|
||||
return a.getDept()-b.getDept();
|
||||
}
|
||||
}
|
51
Lab111-VenbergGE/src/Employee.java
Normal file
51
Lab111-VenbergGE/src/Employee.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
28
Lab111-VenbergGE/src/HireDateComparator.java
Normal file
28
Lab111-VenbergGE/src/HireDateComparator.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gabriel Venberg
|
||||
*/
|
||||
public class HireDateComparator implements Comparator<Employee>{
|
||||
|
||||
public int compare(Employee a, Employee b){
|
||||
return a.getHireDate()-b.getHireDate();
|
||||
}
|
||||
|
||||
}
|
28
Lab111-VenbergGE/src/IDComparator.java
Normal file
28
Lab111-VenbergGE/src/IDComparator.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gabriel Venberg
|
||||
*/
|
||||
public class IDComparator implements Comparator<Employee>{
|
||||
|
||||
public int compare(Employee a, Employee b){
|
||||
return a.getSSN()-b.getSSN();
|
||||
}
|
||||
|
||||
}
|
21
Lab111-VenbergGE/src/LinkedQueue.java
Normal file
21
Lab111-VenbergGE/src/LinkedQueue.java
Normal file
|
@ -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<E> implements Queue<E>{
|
||||
private SinglyLinkedList<E> 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();}
|
||||
}
|
26
Lab111-VenbergGE/src/NameComparator.java
Normal file
26
Lab111-VenbergGE/src/NameComparator.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gabriel Venberg
|
||||
*/
|
||||
public class NameComparator implements Comparator<Employee>{
|
||||
public int compare(Employee a, Employee b){
|
||||
return a.getName().compareTo(b.getName());
|
||||
}
|
||||
}
|
28
Lab111-VenbergGE/src/Queue.java
Normal file
28
Lab111-VenbergGE/src/Queue.java
Normal file
|
@ -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<E> {
|
||||
/** 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();
|
||||
}
|
78
Lab111-VenbergGE/src/SinglyLinkedList.java
Normal file
78
Lab111-VenbergGE/src/SinglyLinkedList.java
Normal file
|
@ -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<E> {
|
||||
|
||||
private static class Node<E> {
|
||||
private E element; //refrence to element stored at this node
|
||||
private Node<E> next; //refrence to subsequent node of list
|
||||
|
||||
public Node(E e, Node<E> n){
|
||||
element = e;
|
||||
next = n;
|
||||
}
|
||||
|
||||
public E getElement() {return element;}
|
||||
|
||||
public Node<E> getNext() {return next;}
|
||||
|
||||
public void setNext(Node<E> n) {next = n;}
|
||||
}
|
||||
|
||||
//instance variables of SinglyLinkedList
|
||||
private Node<E> head = null;//head node of list
|
||||
private Node<E> 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<E> 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;
|
||||
}
|
||||
}
|
205
Lab111-VenbergGE/src/Sort.java
Normal file
205
Lab111-VenbergGE/src/Sort.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class containing a bunch of static sort methods.
|
||||
* @author Gabriel Venberg
|
||||
*/
|
||||
public class Sort {
|
||||
|
||||
/**
|
||||
* copies an array
|
||||
* @param <K> type of array
|
||||
* @param toCopy array to copy
|
||||
* @return copy of array
|
||||
*/
|
||||
public static <K> K[] arrayCopyRange(K[] toCopy, int start, int end){
|
||||
K[] output = (K[]) new Object[end-start];
|
||||
for(int i=start; i<end; i++){
|
||||
output[i-start]=toCopy[i];
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static <K> LinkedQueue<K> arrayToQueue(K[] toConvert){
|
||||
LinkedQueue<K> output = new LinkedQueue<>();
|
||||
for(int i=0; i<toConvert.length; i++){
|
||||
output.enqueue(toConvert[i]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static <K> K[] queueToArray(LinkedQueue<K> toConvert){
|
||||
K[] output = (K[]) new Object[toConvert.size()];
|
||||
for(int i=0; i<output.length; i++){
|
||||
output[i]=toConvert.dequeue();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts a list in place with a bubble sort. stable
|
||||
* @param <K> type of array
|
||||
* @param toSort array to sort
|
||||
* @param comp comparator to use.
|
||||
*/
|
||||
public static <K> void badBubbleSort(K[] toSort, Comparator<K> comp){
|
||||
//dont want to be constantly creating and destroying this if we dont have to.
|
||||
K tmp;
|
||||
for(int i=0; i<toSort.length; i++){
|
||||
//start at one to avoid arrayIndexOutOfBounds
|
||||
for(int j=1; j<toSort.length; j++){
|
||||
if(comp.compare(toSort[j-1], toSort[j])>0){
|
||||
//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 <K> type of array
|
||||
* @param toSort array to sort
|
||||
* @param comp comparator to use.
|
||||
*/
|
||||
public static <K> void bubbleSort(K[] toSort, Comparator<K> 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; i<sortTo; i++){
|
||||
if(comp.compare(toSort[i-1], toSort[i])>0){
|
||||
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 <K> 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 <K> void merge(K[] A, K[] B, K[] C, Comparator<K> comp){
|
||||
//counters for arrays A and B
|
||||
int a=0, b=0;
|
||||
while(a+b<C.length){
|
||||
//the first part is so that if we have 'emptied' out one list, the rest of the other list is rapidly copied across. the <=0 should make the mergesort stable.
|
||||
if(b==B.length||(a<A.length&&comp.compare(A[a], B[b])<=0))
|
||||
//put next element of a into c and increment a's counter.
|
||||
C[a+b]=A[a++];
|
||||
else{
|
||||
//put next element of b into c and increment b's counter.
|
||||
C[a+b]=B[b++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts an array in place with a mergesort. stable
|
||||
* @param <K> type of array
|
||||
* @param toSort array to sort
|
||||
* @param comp comparator to use
|
||||
*/
|
||||
public static <K> void mergeSort(K[] toSort, Comparator<K> 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 <K> type of array
|
||||
* @param toSort array to sort
|
||||
* @param comp comparator to use
|
||||
*/
|
||||
public static <K> void quickSort(Queue<K> toSort, Comparator<K> comp){
|
||||
//queue is trivially sorted
|
||||
if(toSort.size()<2){return;}
|
||||
//divide
|
||||
K pivot=toSort.first();
|
||||
Queue<K> less = new LinkedQueue<>();
|
||||
Queue<K> equal = new LinkedQueue<>();
|
||||
Queue<K> 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 <K> type of array
|
||||
* @param toSort array to sort
|
||||
* @param comp comparator to use
|
||||
*/
|
||||
public static <K> K[] quickSortArray(K[] toSort, Comparator<K> comp){
|
||||
LinkedQueue<K> tmp = arrayToQueue(toSort);
|
||||
quickSort(tmp, comp);
|
||||
return queueToArray(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts an array based on multiple keys, from least
|
||||
* @param <K> 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 <K> void radixSort(K[] toSort, Comparator<K>[] 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]);
|
||||
}
|
||||
}
|
||||
}
|
104
Lab111-VenbergGE/src/client.java
Normal file
104
Lab111-VenbergGE/src/client.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @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<employees.length; i++){
|
||||
employees[i]=new Employee(rgen.nextInt(100000000), rgen.nextInt(4)+1, rgen.nextInt(26)+1995, randomPrintableString());
|
||||
}
|
||||
|
||||
//tried doing this with a method, did NOT want to work with me for some reason. Even tried using the arrayCopyRange method in employee, kept giving me:
|
||||
//Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [LEmployee; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [LEmployee;
|
||||
for(int i=0; i<employees.length; i++){
|
||||
tmp[i]=employees[i];
|
||||
}
|
||||
startTime=System.nanoTime();
|
||||
Sort.mergeSort(tmp, compareName);
|
||||
endTime=System.nanoTime();
|
||||
data[0][0]="merge sort by name";
|
||||
data[0][1]=String.format("%,d", endTime-startTime);
|
||||
|
||||
for(int i=0; i<employees.length; i++){
|
||||
tmp[i]=employees[i];
|
||||
} startTime=System.nanoTime();
|
||||
Sort.quickSortArray(tmp, compareDept);
|
||||
endTime=System.nanoTime();
|
||||
data[1][0]="quick sort by dept";
|
||||
data[1][1]=String.format("%,d", endTime-startTime);
|
||||
|
||||
for(int i=0; i<employees.length; i++){
|
||||
tmp[i]=employees[i];
|
||||
}
|
||||
startTime=System.nanoTime();
|
||||
Sort.bubbleSort(tmp, compareID);
|
||||
endTime=System.nanoTime();
|
||||
data[2][0]="bubble sort by ID";
|
||||
data[2][1]=String.format("%,d", endTime-startTime);
|
||||
|
||||
for(int i=0; i<employees.length; i++){
|
||||
tmp[i]=employees[i];
|
||||
}
|
||||
Comparator[] radixComparator = {compareDept, compareHireDate, compareName};
|
||||
startTime=System.nanoTime();
|
||||
Sort.radixSort(tmp, radixComparator);
|
||||
endTime=System.nanoTime();
|
||||
data[3][0]="radix sort";
|
||||
data[3][1]=String.format("%,d", endTime-startTime);
|
||||
|
||||
String[] colHeaders = {"sort", "nanoseconds taken"};
|
||||
System.out.println(ASCIITable.render(data, 2, "time of sorts", colHeaders));
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a random string made of lowercase letters, 5 to 10 chars long. not general purpouse.
|
||||
* @return
|
||||
*/
|
||||
public static String randomPrintableString(){
|
||||
Random rgen = new Random();
|
||||
int length = rgen.nextInt(6)+5;
|
||||
String output="";
|
||||
String letters = "qwertyuiopasdfghjklzxcvbnm";
|
||||
for(int i=0; i<length; i++){
|
||||
output = output+letters.charAt(rgen.nextInt(letters.length()));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
private static <K> K[] arrayCopy(K[] toCopy){
|
||||
K[] output = (K[]) new Object[toCopy.length];
|
||||
for(int i=0; i<toCopy.length; i++){
|
||||
output[i]=toCopy[i];
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
Reference in a new issue