refactor to use polymorphism

This commit is contained in:
2020-06-17 22:15:00 -05:00
parent fe9000267a
commit 5d9c8ebde6
14 changed files with 82 additions and 152 deletions

View File

@@ -177,7 +177,7 @@ public class AlgorithmTester{
for(SortResult e: results){ for(SortResult e: results){
if(e!=null){ if(e!=null){
if(print){ if(print){
for(int i: e.getSortedArray()){ for(int i: e.getSortedNumbers()){
System.out.print(i+" "); System.out.print(i+" ");
} }
System.out.print("\n"); System.out.print("\n");
@@ -245,7 +245,7 @@ public class AlgorithmTester{
} }
boolean selection = sortingAlgoChoices[0]; boolean selection = sortingAlgoChoices[0];
boolean insertion = sortingAlgoChoices[1]; boolean insertion = sortingAlgoChoices[1];
ArrayList<WordSortResult> results = new ArrayList<WordSortResult>(); ArrayList<SortResult> results = new ArrayList<SortResult>();
if(selection){ if(selection){
WordSelectionSorter selSorter = new WordSelectionSorter(reader); WordSelectionSorter selSorter = new WordSelectionSorter(reader);
results.add(selSorter.measuredSort()); results.add(selSorter.measuredSort());
@@ -254,15 +254,15 @@ public class AlgorithmTester{
WordInsertionSorter inSorter = new WordInsertionSorter(reader); WordInsertionSorter inSorter = new WordInsertionSorter(reader);
results.add(inSorter.measuredSort()); results.add(inSorter.measuredSort());
} }
for(WordSortResult e: results){ for(SortResult e: results){
if(e!=null){ if(e!=null){
if(print){ if(print){
for(String i: e.getSortedArray()){ for(String i: e.getSortedWords()){
System.out.print(i+" "); System.out.print(i+" ");
} }
System.out.print("\n"); System.out.print("\n");
} }
System.out.println("\n"+e.getSortType()+" of "+e.getSortCount()+" words from "+e.getMin()+" to "+e.getMax()+" took:"); System.out.println("\n"+e.getSortType()+" of "+e.getSortCount()+" words from "+e.getFirst()+" to "+e.getLast()+" took:");
System.out.println(e.getComparisonsUsed()+" comparisons"); System.out.println(e.getComparisonsUsed()+" comparisons");
System.out.println(e.getWritesUsed()+" write operations"); System.out.println(e.getWritesUsed()+" write operations");
System.out.println(e.getTimeUsed()+" milliseconds"); System.out.println(e.getTimeUsed()+" milliseconds");

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class NumberBubbleSorter extends NumberSorter{ public class NumberBubbleSorter extends Sorter{
//a class to sort arrays of numbers using bubble sort //a class to sort arrays of numbers using bubble sort
public NumberBubbleSorter(RandomNumberFileReader reader){ public NumberBubbleSorter(RandomNumberFileReader reader){

View File

@@ -2,7 +2,7 @@ package Sorting;
import java.util.Arrays; import java.util.Arrays;
public class NumberCountingSorter extends NumberSorter{ public class NumberCountingSorter extends Sorter{
public NumberCountingSorter(RandomNumberFileReader reader){ public NumberCountingSorter(RandomNumberFileReader reader){
super("counting sort", reader); super("counting sort", reader);

View File

@@ -3,7 +3,7 @@ package Sorting;
//import java.util.Arrays; //import java.util.Arrays;
//import java.util.List; //import java.util.List;
public class NumberInsertionSorter extends NumberSorter{ public class NumberInsertionSorter extends Sorter{
public NumberInsertionSorter(RandomNumberFileReader reader){ public NumberInsertionSorter(RandomNumberFileReader reader){
super("insertion sort", reader); super("insertion sort", reader);

View File

@@ -4,7 +4,7 @@ import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.ListIterator; import java.util.ListIterator;
public class NumberInsertionSorterLinkedList extends NumberSorter{ public class NumberInsertionSorterLinkedList extends Sorter{
public NumberInsertionSorterLinkedList(RandomNumberFileReader reader){ public NumberInsertionSorterLinkedList(RandomNumberFileReader reader){
super("insertion sort (linked list)", reader); super("insertion sort (linked list)", reader);

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class NumberMergeSorter extends NumberSorter{ public class NumberMergeSorter extends Sorter{
public NumberMergeSorter(RandomNumberFileReader reader){ public NumberMergeSorter(RandomNumberFileReader reader){
super("merge sort",reader); super("merge sort",reader);

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class NumberQuickSorter extends NumberSorter{ public class NumberQuickSorter extends Sorter{
public NumberQuickSorter(RandomNumberFileReader reader){ public NumberQuickSorter(RandomNumberFileReader reader){
super("quick sort", reader); super("quick sort", reader);

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class NumberSelectionSorter extends NumberSorter { public class NumberSelectionSorter extends Sorter {
//a class to sort an array of numbers using selection sort //a class to sort an array of numbers using selection sort
public NumberSelectionSorter(RandomNumberFileReader reader){ public NumberSelectionSorter(RandomNumberFileReader reader){
super("selection sort", reader); super("selection sort", reader);

View File

@@ -23,6 +23,7 @@ public class SortResult {
private String sortType; private String sortType;
private Integer [] sortedArray; private Integer [] sortedArray;
private String[] sortedWordArray;
private String comparisonsUsed; private String comparisonsUsed;
private String writesUsed; private String writesUsed;
private String timeUsed; private String timeUsed;
@@ -41,6 +42,21 @@ public class SortResult {
timeUsed = nf.format(t.toMillis()); timeUsed = nf.format(t.toMillis());
} }
public SortResult(String st, String[] a, long c, long w, Duration t){
sortType = st;
sortedWordArray = a;
NumberFormat nf = NumberFormat.getInstance(Locale.US);
if(c==0){
comparisonsUsed = "No";
}
else{
comparisonsUsed = nf.format(c);
}
writesUsed = nf.format(w);
timeUsed = nf.format(t.toMillis());
}
public SortResult(String st, Integer[] a, Duration t){ public SortResult(String st, Integer[] a, Duration t){
sortType = st; sortType = st;
sortedArray = a; sortedArray = a;
@@ -54,10 +70,14 @@ public class SortResult {
return sortType; return sortType;
} }
public Integer[] getSortedArray(){ public Integer[] getSortedNumbers(){
return sortedArray; return sortedArray;
} }
public String[] getSortedWords(){
return sortedWordArray;
}
public String getTimeUsed(){ public String getTimeUsed(){
return timeUsed; return timeUsed;
} }
@@ -72,7 +92,7 @@ public class SortResult {
public String getSortCount(){ public String getSortCount(){
NumberFormat nf = NumberFormat.getInstance(Locale.US); NumberFormat nf = NumberFormat.getInstance(Locale.US);
return nf.format(sortedArray.length); return nf.format(sortedWordArray.length);
} }
public String getMin(){ public String getMin(){
@@ -85,4 +105,12 @@ public class SortResult {
return nf.format(sortedArray[sortedArray.length-1]); return nf.format(sortedArray[sortedArray.length-1]);
} }
public String getFirst(){
return sortedWordArray[0];
}
public String getLast(){
return sortedWordArray[sortedWordArray.length-1];
}
} }

View File

@@ -8,20 +8,30 @@ import java.lang.Integer;
* This is an abstract class, its subclasses will inherit its methods and instance * This is an abstract class, its subclasses will inherit its methods and instance
* fields. Any abstract methods will have to be implemented in the subclasses. * fields. Any abstract methods will have to be implemented in the subclasses.
*/ */
abstract class NumberSorter { abstract class Sorter {
protected String sortType; protected String sortType;
protected Integer[] numbers; protected Integer[] numbers;
protected String[] words;
protected long comparisonsUsed = 0; protected long comparisonsUsed = 0;
protected long writesUsed=0; protected long writesUsed=0;
protected boolean sortingNumbers;
public NumberSorter(String st, RandomNumberFileReader reader){ public Sorter(String st, RandomNumberFileReader reader){
sortType=st; sortType=st;
//RandomNumberFileReader reader = new RandomNumberFileReader(filename); //RandomNumberFileReader reader = new RandomNumberFileReader(filename);
numbers = new Integer[reader.getNumbers().size()]; numbers = new Integer[reader.getNumbers().size()];
reader.getNumbers().toArray(numbers); reader.getNumbers().toArray(numbers);
sortingNumbers = true;
} }
public Sorter(String sortType, RandomWordFileReader reader){
this.sortType = sortType;
words = new String[reader.getWords().size()];
reader.getWords().toArray(words);
sortingNumbers = false;
}
/** /**
* An abstract sorting method. Each subclass will have to implement its own * An abstract sorting method. Each subclass will have to implement its own
* version of this method. * version of this method.
@@ -41,6 +51,13 @@ abstract class NumberSorter {
writesUsed+=2; writesUsed+=2;
} }
protected void swap(String[] array, int indexA, int indexB){
String tmp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = tmp;
writesUsed+=2;
}
/** /**
* A method to compare two integers and increment the comparisonsUsed counter. * A method to compare two integers and increment the comparisonsUsed counter.
* @param a the first integer to be compared * @param a the first integer to be compared
@@ -51,6 +68,11 @@ abstract class NumberSorter {
comparisonsUsed++; comparisonsUsed++;
return Integer.compare(a,b); return Integer.compare(a,b);
} }
protected int compare(String a, String b){
comparisonsUsed++;
return a.compareTo(b);
}
/** /**
* Writes a value into an array at a specific index and increments the writesUsed counter. * Writes a value into an array at a specific index and increments the writesUsed counter.
@@ -63,17 +85,29 @@ abstract class NumberSorter {
writesUsed++; writesUsed++;
} }
protected void writeToArray(String[] array, int index, String value){
array[index]=value;
writesUsed++;
}
/** /**
* Measures how long the sort() function takes to run * Measures how long the sort() function takes to run
* @return returns a SortResult object with the name of the sorting algorithm used, the sorted array of numbers, the number of comparisons used to sort, and the number of writes to arrays used to sort * @return returns a SortResult object with the name of the sorting algorithm used, the sorted array of numbers, the number of comparisons used to sort, and the number of writes to arrays used to sort
*/ */
public SortResult measuredSort(){ public SortResult measuredSort(){
if(numbers.length!=0){ if(numbers!=null||words!=null){
Instant start = Instant.now(); Instant start = Instant.now();
this.sort(); this.sort();
Instant end = Instant.now(); Instant end = Instant.now();
Duration time = Duration.between(start,end); Duration time = Duration.between(start,end);
SortResult output = new SortResult(sortType, numbers, comparisonsUsed, writesUsed, time); SortResult output;
if(sortingNumbers){
output = new SortResult(sortType, numbers, comparisonsUsed, writesUsed, time);
}
else{
output = new SortResult(sortType, words, comparisonsUsed, writesUsed, time);
}
return output; return output;
} }
else{ else{

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class WordInsertionSorter extends WordSorter { public class WordInsertionSorter extends Sorter {
public WordInsertionSorter(RandomWordFileReader reader){ public WordInsertionSorter(RandomWordFileReader reader){
super("insertion sort", reader); super("insertion sort", reader);

View File

@@ -1,6 +1,6 @@
package Sorting; package Sorting;
public class WordSelectionSorter extends WordSorter{ public class WordSelectionSorter extends Sorter{
public WordSelectionSorter(RandomWordFileReader reader){ public WordSelectionSorter(RandomWordFileReader reader){
super("selection sort", reader); super("selection sort", reader);

View File

@@ -1,78 +0,0 @@
package Sorting;
import java.time.Duration;
import java.util.Locale;
import java.text.NumberFormat;
/**
* This is a class to hold the efficiencty results of a sorter. We will use this
* because we can only have one return value from a method, but want to get more
* than one piece of data from each sorter.
*
* We will write several constructors for this class, as not all sorting algorithms
* will use all of the fields. For example, radix sort does not use comparisons.
* Counting sort does not use swaps.
*
* Writing several constructors for difference situations is an example of
* "polymorphism" -- the quality of object oriented design that lets a single
* interface have multiple implementations.
*
* The methods that call the constructor of SortResult don't know it has lots of
* them, they only know what data they have to give it.
*/
public class WordSortResult {
private String sortType;
private String[] sortedArray;
private String comparisonsUsed;
private String writesUsed;
private String timeUsed;
public WordSortResult(String st, String[] a, long c, long w, Duration t){
sortType = st;
sortedArray = a;
NumberFormat nf = NumberFormat.getInstance(Locale.US);
if(c==0){
comparisonsUsed = "No";
}
else{
comparisonsUsed = nf.format(c);
}
writesUsed = nf.format(w);
timeUsed = nf.format(t.toMillis());
}
public String getSortType(){
return sortType;
}
public String[] getSortedArray(){
return sortedArray;
}
public String getTimeUsed(){
return timeUsed;
}
public String getComparisonsUsed(){
return comparisonsUsed;
}
public String getWritesUsed(){
return writesUsed;
}
public String getSortCount(){
NumberFormat nf = NumberFormat.getInstance(Locale.US);
return nf.format(sortedArray.length);
}
public String getMin(){
return sortedArray[0];
}
public String getMax(){
return sortedArray[sortedArray.length-1];
}
}

View File

@@ -1,54 +0,0 @@
package Sorting;
import java.time.Duration;
import java.time.Instant;
public abstract class WordSorter {
protected String sortType;
protected String[] words;
protected long comparisonsUsed = 0;
protected long writesUsed=0;
public WordSorter(String sortType, RandomWordFileReader reader){
this.sortType = sortType;
words = new String[reader.getWords().size()];
reader.getWords().toArray(words);
}
abstract void sort();
protected int compare(String a, String b){
comparisonsUsed++;
return a.compareTo(b);
}
protected void writeToArray(String[] array, int index, String value){
array[index]=value;
writesUsed++;
}
protected void swap(String[] array, int indexA, int indexB){
String tmp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = tmp;
writesUsed+=2;
}
public WordSortResult measuredSort(){
if(words.length!=0){
Instant start = Instant.now();
this.sort();
Instant end = Instant.now();
Duration time = Duration.between(start,end);
WordSortResult output = new WordSortResult(sortType, words, comparisonsUsed, writesUsed, time);
return output;
}
else{
System.out.println("Nothing to sort using "+sortType);
return null;
}
}
}