Lab109
This commit is contained in:
		
							parent
							
								
									b1fe8d6ea1
								
							
						
					
					
						commit
						29c576c988
					
				
					 9 changed files with 577 additions and 0 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -46,3 +46,4 @@ hs_err_pid*
 | 
				
			||||||
/Lab108-VenbergGE/nbproject/private/
 | 
					/Lab108-VenbergGE/nbproject/private/
 | 
				
			||||||
/Lab108-VenbergGE/build/
 | 
					/Lab108-VenbergGE/build/
 | 
				
			||||||
/Lab108-VenbergGE/dist/
 | 
					/Lab108-VenbergGE/dist/
 | 
				
			||||||
 | 
					/Lab109/build/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										181
									
								
								Lab109/src/ASCIITable.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								Lab109/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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								Lab109/src/AbstractPriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Lab109/src/AbstractPriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Comparator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data Structures & Algorithms 6th Edition 
 | 
				
			||||||
 | 
					 * Goodrich, Tamassia, Goldwasser
 | 
				
			||||||
 | 
					 * Code Fragments 9.6
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * An implementation of the AbstractPriorityQueue class
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public abstract class AbstractPriorityQueue<K,V> implements PriorityQueue<K,V> {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //nested PQEntry class
 | 
				
			||||||
 | 
					    protected static class PQEntry<K,V> implements Entry<K,V> {
 | 
				
			||||||
 | 
					        private K k;
 | 
				
			||||||
 | 
					        private V v;
 | 
				
			||||||
 | 
					        public PQEntry(K key, V value){
 | 
				
			||||||
 | 
					            k=key;
 | 
				
			||||||
 | 
					            v=value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        //methods of entry interface
 | 
				
			||||||
 | 
					        public K getKey(){return k;}
 | 
				
			||||||
 | 
					        public V getValue(){return v;}
 | 
				
			||||||
 | 
					        //utilites not exposed
 | 
				
			||||||
 | 
					        protected void setKey(K key){k=key;}
 | 
				
			||||||
 | 
					        protected void setValue(V value){v=value;}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    //end of nested class
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** the comparator defining ordering of keys into the priority queue.*/
 | 
				
			||||||
 | 
					    private Comparator<K> comp;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Creates an empty priority queue using the given comparator to order keys. */
 | 
				
			||||||
 | 
					    protected AbstractPriorityQueue(Comparator<K> c){comp=c;}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** creates an empty priority queue based on the natrual ordering of its keys */
 | 
				
			||||||
 | 
					    protected AbstractPriorityQueue(){this(new DefaultComparator<K>());}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** method for comparing two entries according to the key*/
 | 
				
			||||||
 | 
					    protected int compare(Entry<K,V> a, Entry<K,V> b){
 | 
				
			||||||
 | 
					        return comp.compare(a.getKey(), b.getKey());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** determines whether a key is valid*/
 | 
				
			||||||
 | 
					    protected boolean checkKey(K key) throws IllegalArgumentException {
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					            return (comp.compare(key,key)==0); //see if the key can be compared
 | 
				
			||||||
 | 
					        }catch(ClassCastException e){
 | 
				
			||||||
 | 
					            throw new IllegalArgumentException("incompatable key");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**tests whether the priority queue is empty*/
 | 
				
			||||||
 | 
					    public boolean isEmpty(){return size()==0;}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										122
									
								
								Lab109/src/Client.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								Lab109/src/Client.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,122 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Scanner;
 | 
				
			||||||
 | 
					import javax.swing.JOptionPane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 p copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class Client {
 | 
				
			||||||
 | 
					    public static void main(String[] args){
 | 
				
			||||||
 | 
					         String filePath = (String) JOptionPane.showInputDialog(null, "Enter the path of the file", "/home/toric/Downloads/words/words.txt");
 | 
				
			||||||
 | 
					        File file = new File(filePath);
 | 
				
			||||||
 | 
					        Scanner fileContents = null;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            fileContents = new Scanner(file);
 | 
				
			||||||
 | 
					        } catch (FileNotFoundException ex) {
 | 
				
			||||||
 | 
					            JOptionPane.showMessageDialog(null, "file does not exist.");
 | 
				
			||||||
 | 
					            System.exit(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        ArrayList<String> words = new ArrayList<>();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        while(fileContents.hasNext()){
 | 
				
			||||||
 | 
					            words.add(fileContents.next());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        String[][] hashData = new String[15][3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(int a=30; a<45; a++){
 | 
				
			||||||
 | 
					            //tried using this using an array of buckets, it got... messy
 | 
				
			||||||
 | 
					            HeapPriorityQueue<Integer,Integer> hashes = new HeapPriorityQueue<>();
 | 
				
			||||||
 | 
					            for(int i=0; i< words.size(); i++){
 | 
				
			||||||
 | 
					                //the value doesnt matter
 | 
				
			||||||
 | 
					                hashes.insert(Hashing.polynomialHashCode(words.get(i), a), a);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            int totalColisions=0, maxColisions=0, currentColisions=0;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            //used to detect 'boundries' between groups of hash codes.
 | 
				
			||||||
 | 
					            int prevHash=hashes.removeMin().getKey();
 | 
				
			||||||
 | 
					            while(!hashes.isEmpty()){
 | 
				
			||||||
 | 
					                //if its the same as the previous, it is p collision.
 | 
				
			||||||
 | 
					                int currentHash=hashes.removeMin().getKey();
 | 
				
			||||||
 | 
					                if(currentHash==prevHash){
 | 
				
			||||||
 | 
					                    currentColisions++;
 | 
				
			||||||
 | 
					                    totalColisions++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                //we have reached the end of that 'block', store our max collisions (if applicable), and reset current colisions.
 | 
				
			||||||
 | 
					                else{
 | 
				
			||||||
 | 
					                    maxColisions=Math.max(maxColisions, currentColisions);
 | 
				
			||||||
 | 
					                    currentColisions=0;
 | 
				
			||||||
 | 
					                    prevHash=currentHash;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            //write the table for value of a
 | 
				
			||||||
 | 
					            hashData[a-30][0]=String.format("%,d", a);
 | 
				
			||||||
 | 
					            hashData[a-30][1]=String.format("%,d", maxColisions);
 | 
				
			||||||
 | 
					            hashData[a-30][2]=String.format("%,d", totalColisions);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String[] colHeaders={"a", "max collisions", "total collisions"};
 | 
				
			||||||
 | 
					        System.out.println(ASCIITable.render(hashData, 2, "Polynomial hash code", colHeaders));
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //lets have p be 92000. (for appropriate load factor). first prime number after is 92003
 | 
				
			||||||
 | 
					        String[][] compressionData = new String[10][3];
 | 
				
			||||||
 | 
					        for(int p=91998; p<92008; p++){
 | 
				
			||||||
 | 
					            //tried using this using an array of buckets, it got... messy
 | 
				
			||||||
 | 
					            HeapPriorityQueue<Integer,Integer> compressions = new HeapPriorityQueue<>();
 | 
				
			||||||
 | 
					            for(int i=0; i< words.size(); i++){
 | 
				
			||||||
 | 
					                //the value doesnt matter
 | 
				
			||||||
 | 
					                compressions.insert(Hashing.madCompression(Hashing.polynomialHashCode(words.get(i), 33), 92000, p, 6578, 75245), p);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            int totalColisions=0, maxColisions=0, currentColisions=0;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            //used to detect 'boundries' between groups of hash codes.
 | 
				
			||||||
 | 
					            int prevCompression=compressions.removeMin().getKey();
 | 
				
			||||||
 | 
					            while(!compressions.isEmpty()){
 | 
				
			||||||
 | 
					                //if its the same as the previous, it is p collision.
 | 
				
			||||||
 | 
					                int currentCompression=compressions.removeMin().getKey();
 | 
				
			||||||
 | 
					                if(currentCompression==prevCompression){
 | 
				
			||||||
 | 
					                    currentColisions++;
 | 
				
			||||||
 | 
					                    totalColisions++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                //we have reached the end of that 'block', store our max collisions (if applicable), and reset current colisions.
 | 
				
			||||||
 | 
					                else{
 | 
				
			||||||
 | 
					                    maxColisions=Math.max(maxColisions, currentColisions);
 | 
				
			||||||
 | 
					                    currentColisions=0;
 | 
				
			||||||
 | 
					                    prevCompression=currentCompression;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            //write the table for value of p
 | 
				
			||||||
 | 
					            compressionData[p-91998][0]=String.format("%,d", p);
 | 
				
			||||||
 | 
					            compressionData[p-91998][1]=String.format("%,d", maxColisions);
 | 
				
			||||||
 | 
					            compressionData[p-91998][2]=String.format("%,d", totalColisions);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        String[] colHeaders2={"p", "max collisions", "total collisions"};
 | 
				
			||||||
 | 
					        System.out.println(ASCIITable.render(compressionData, 2, "MAD compression", colHeaders2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								Lab109/src/DefaultComparator.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Lab109/src/DefaultComparator.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Comparator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data Structures & Algorithms 6th Edition 
 | 
				
			||||||
 | 
					 * Goodrich, Tamassia, Goldwasser
 | 
				
			||||||
 | 
					 * Code Fragments 9.4
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * An implementation of the DefaultComparator class
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class DefaultComparator<E> implements Comparator<E> {
 | 
				
			||||||
 | 
					    public int compare(E a, E b) throws ClassCastException{
 | 
				
			||||||
 | 
					        return((Comparable<E>)a).compareTo(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								Lab109/src/Entry.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Lab109/src/Entry.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data Structures & Algorithms 6th Edition 
 | 
				
			||||||
 | 
					 * Goodrich, Tamassia, Goldwasser
 | 
				
			||||||
 | 
					 * Code Fragments 9.1
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * An implementation of the Entry Interface
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface Entry <K,V>{
 | 
				
			||||||
 | 
					    K getKey();
 | 
				
			||||||
 | 
					    V getValue();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								Lab109/src/Hashing.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								Lab109/src/Hashing.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,57 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * an implementation of polynomial hash code and MAD compression functions
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class Hashing {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * hashes a given string (x0,x1,...,xn-1) by x0a^n-1+x1a^n-2+...+xn-2a+xn-1. using a given value of a
 | 
				
			||||||
 | 
					     * @param value the string to hash
 | 
				
			||||||
 | 
					     * @param a the value of a to use
 | 
				
			||||||
 | 
					     * @return an int representing the resulting hash.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static int polynomialHashCode(String value, int a){
 | 
				
			||||||
 | 
					        //due to twos compliment math, we dont actually need to use longs to detect rollover, and can just use a mask to ignore the sign bit!
 | 
				
			||||||
 | 
					        //also, wasted 2 hours because I had set this to MIN_VALUE....
 | 
				
			||||||
 | 
					        final int mask = Integer.MAX_VALUE;
 | 
				
			||||||
 | 
					        int hash=0;
 | 
				
			||||||
 | 
					        //using horners rule iteratively
 | 
				
			||||||
 | 
					        for(int i=0; i<value.length(); i++){
 | 
				
			||||||
 | 
					            hash = (hash * a) + (int) value.charAt(i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // im *pretty sure* we only need to zero the sign bit once... will test
 | 
				
			||||||
 | 
					        return hash&mask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * compresses a hash code with by multiply add divide method with given constants
 | 
				
			||||||
 | 
					     * @param value the hash code to compress
 | 
				
			||||||
 | 
					     * @param N the given value of N (should be the size of your bucket array if using to make hash table)
 | 
				
			||||||
 | 
					     * @param p should be a prime number larger than N
 | 
				
			||||||
 | 
					     * @param a random value between 1 and p-1
 | 
				
			||||||
 | 
					     * @param b random value between 0 and p-1
 | 
				
			||||||
 | 
					     * @return the compressed hash.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static int madCompression(int value, int N, int p, int a, int b) throws IllegalArgumentException{
 | 
				
			||||||
 | 
					        if(0>b||b>p-1){throw new IllegalArgumentException("b needs to be between 0 and p-1, inclusive.");}
 | 
				
			||||||
 | 
					        if(0>=a||a>p-1){throw new IllegalArgumentException("a needs to be betwwen 1 and p-1, inclusive.");}
 | 
				
			||||||
 | 
					        return ((a*value+b)%p)%N;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										101
									
								
								Lab109/src/HeapPriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								Lab109/src/HeapPriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,101 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Comparator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data Structures & Algorithms 6th Edition 
 | 
				
			||||||
 | 
					 * Goodrich, Tamassia, Goldwasser
 | 
				
			||||||
 | 
					 * Code Fragments 9.8-9.9
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * An implementation of the heapPriortyQueue class
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class HeapPriorityQueue<K,V> extends AbstractPriorityQueue<K,V> {
 | 
				
			||||||
 | 
					    /** primary collection of priorty queue entries*/
 | 
				
			||||||
 | 
					    protected ArrayList<Entry<K,V>> heap = new ArrayList<>();
 | 
				
			||||||
 | 
					    /**creates an empty priority queue based on the natrual ordering of its keys*/
 | 
				
			||||||
 | 
					    public HeapPriorityQueue(){super();}
 | 
				
			||||||
 | 
					    /** creates an empty priorty queue using the given comparator to order keys.*/
 | 
				
			||||||
 | 
					    public HeapPriorityQueue(Comparator<K> comp){super(comp);}
 | 
				
			||||||
 | 
					    //protected utilities
 | 
				
			||||||
 | 
					    protected int parent(int j){return(j-1)/2;}
 | 
				
			||||||
 | 
					    protected int left(int j){return 2*j+1;}
 | 
				
			||||||
 | 
					    protected int right(int j){return 2*j+2;}
 | 
				
			||||||
 | 
					    protected boolean hasLeft(int j){return left(j)<heap.size();}
 | 
				
			||||||
 | 
					    protected boolean hasRight(int j){return right(j)<heap.size();}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    protected void swap(int i, int j){
 | 
				
			||||||
 | 
					        Entry<K,V> temp = heap.get(i);
 | 
				
			||||||
 | 
					        heap.set(i, heap.get(j));
 | 
				
			||||||
 | 
					        heap.set(j, temp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** moves the entry at index j higher, if necessary, to restore heap property*/
 | 
				
			||||||
 | 
					    protected void upheap(int j){
 | 
				
			||||||
 | 
					        //continue till reaching root or break statemetnt
 | 
				
			||||||
 | 
					        while(j>0){
 | 
				
			||||||
 | 
					            int p=parent(j);
 | 
				
			||||||
 | 
					            //heap verified
 | 
				
			||||||
 | 
					            if(compare(heap.get(j), heap.get(p))>=0){break;}
 | 
				
			||||||
 | 
					            swap(j,p);
 | 
				
			||||||
 | 
					            //continue from the parents location.
 | 
				
			||||||
 | 
					            j=p;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** moves the entry at index j lower, if necessayr, to restore the heap property */
 | 
				
			||||||
 | 
					    protected void downheap(int j){
 | 
				
			||||||
 | 
					        while(hasLeft(j)) { //continue to bottom or break statement.
 | 
				
			||||||
 | 
					            int leftIndex=left(j);
 | 
				
			||||||
 | 
					            //although right may be smaller
 | 
				
			||||||
 | 
					            int smallChildIndex = leftIndex;
 | 
				
			||||||
 | 
					            if(hasRight(j)){
 | 
				
			||||||
 | 
					                int rightIndex=right(j);
 | 
				
			||||||
 | 
					                if(compare(heap.get(leftIndex), heap.get(rightIndex))>0){
 | 
				
			||||||
 | 
					                        smallChildIndex=rightIndex;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if(compare(heap.get(smallChildIndex), heap.get(j))>=0){break;}
 | 
				
			||||||
 | 
					            swap(j, smallChildIndex);
 | 
				
			||||||
 | 
					            j=smallChildIndex;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //public methods
 | 
				
			||||||
 | 
					    /**returns the number of items in the priority queue*/
 | 
				
			||||||
 | 
					    public int size(){return heap.size();}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**returns but does not remove an entry with minimal key (if any)*/
 | 
				
			||||||
 | 
					    public Entry<K,V> min(){
 | 
				
			||||||
 | 
					        if(heap.isEmpty()){return null;}
 | 
				
			||||||
 | 
					        return heap.get(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**inserts a key value pair and returns the entry created*/
 | 
				
			||||||
 | 
					    public Entry<K,V> insert(K key, V value) throws IllegalArgumentException{
 | 
				
			||||||
 | 
					        checkKey(key); //could throw exceptions.
 | 
				
			||||||
 | 
					        Entry<K,V> newest = new PQEntry<>(key,value);
 | 
				
			||||||
 | 
					        //add to end of the list
 | 
				
			||||||
 | 
					        heap.add(newest);
 | 
				
			||||||
 | 
					        //and upheap
 | 
				
			||||||
 | 
					        upheap(heap.size()-1);
 | 
				
			||||||
 | 
					        return newest;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**removes and returns an entry with minimal key(if any)*/
 | 
				
			||||||
 | 
					    public Entry<K,V> removeMin(){
 | 
				
			||||||
 | 
					        if(heap.isEmpty()){return null;}
 | 
				
			||||||
 | 
					        Entry<K,V> answer = heap.get(0);
 | 
				
			||||||
 | 
					        //put minimum item at the end
 | 
				
			||||||
 | 
					        swap(0, heap.size()-1);
 | 
				
			||||||
 | 
					        //and remove from list
 | 
				
			||||||
 | 
					        heap.remove(heap.size()-1);
 | 
				
			||||||
 | 
					        //then fix the new root.
 | 
				
			||||||
 | 
					        downheap(0);
 | 
				
			||||||
 | 
					        return answer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								Lab109/src/PriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Lab109/src/PriorityQueue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Data Structures & Algorithms 6th Edition 
 | 
				
			||||||
 | 
					 * Goodrich, Tamassia, Goldwasser
 | 
				
			||||||
 | 
					 * Code Fragments 9.2
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * An implementation of the PriorityQueue interface
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Gabriel Venberg
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface PriorityQueue <K,V> {
 | 
				
			||||||
 | 
					    int size();
 | 
				
			||||||
 | 
					    boolean isEmpty();
 | 
				
			||||||
 | 
					    Entry<K,V> insert(K key, V value) throws IllegalArgumentException;
 | 
				
			||||||
 | 
					    Entry<K,V> min();
 | 
				
			||||||
 | 
					    Entry<K,V> removeMin();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in a new issue