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/build/
 | 
			
		||||
/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