import java.math.BigInteger; /** * A fairly basic implementation of a spparate chanining hashtable * @param the tpe of key * @param the type of value * Implements full separate chaining, but not rehashing. * Similarly, the size of the underlying table, once it is created, cannot * be changed. * @author gtowell * Created: April 25, 2020 */ public class SepChainHT { /** * A Node class for the hashtable * @param * @param */ protected class Node { /** The key, cannot be changed */ final L theKey; /** The value. It can be changed as a second put with the key * will change the value */ W theValue; /** Implements the chain as a linked list. */ Node theNext; /** * Initialize the node */ public Node(L ll, W ww) { theKey=ll; theValue=ww; theNext=null; } /** Print the node, and all subsequent nodes in the linked list */ public String toString() { StringBuilder sb = new StringBuilder(); Node n = this; while(n!=null) { sb.append("{"+n.theKey +","+n.theValue+"}"); //sb.append(n.theKey + " "); n=n.theNext; } return sb.toString(); } /** * Return the length of the chain from this node. * @return the number of subsequent nodes in the linked list */ public int chainLength() { Node n = this; int count = 0; while(n!=null) { count++; n=n.theNext; } return count; } } /** The array holding the hashtable data */ private Node[] backingArray; /** The default size of the backing array */ private static int DEFAULT_CAPACITY = 1009; /** For polynomial accumulation, the multiplier. */ static int POLY_MULT=33; /** Default initialization */ public SepChainHT() { this(DEFAULT_CAPACITY); } /** * Initialize a hashtable of the given size * @param size the size of the hashtable to create */ @SuppressWarnings("unchecked") public SepChainHT(int size) { backingArray = (Node[])new Node[size]; } /** * Implemets poluynomical accumulation on strings. * Since every object can be translated into a string This can be run * on an arbitrary object with no loss of generality. * @param ss the string to generate a hash value for * @return the hash value */ public int stringHasher(String ss) { BigInteger ll = new BigInteger("0"); for (int i=0; i(key, value); } else { Node nod = backingArray[loc]; while (nod !=null) { if (nod.theKey.equals(key)) { nod.theValue=value; break; } else { nod=nod.theNext; } } if (nod==null) { // key is not in the list Node newNod = new Node(key, value); newNod.theNext = backingArray[loc]; backingArray[loc]=newNod; } } } /** * Get the value stored in the hashtable given the key. * @param key the key * @return the value associated with the key */ public V get(K key) { int loc = stringHasher(key.toString()); if (backingArray[loc]==null) { return null; } Node nod = backingArray[loc]; while (nod!=null && !nod.theKey.equals(key)) { nod=nod.theNext; } return nod==null?null:nod.theValue; } /** * The number of distinct keys in the hshtable. * @return The number of distinct keys in the hashtable */ public int size() { int count=0; for (int i=0; i2) { sb.append("\n"+i + " " + backingArray[i].toString()); } } return sb.toString(); } public static void main(String[] args) { SepChainHT sht = new SepChainHT<>(); try { BookReader br = new BookReader("OliverTwist.txt"); for (int i=0; i<500; i++) { String s = br.nextWord(); sht.put(s,s); } } catch (Exception ee) { System.out.println(ee); } System.out.println(sht.size()); System.out.println(sht); //System.out.println(sht.stringHasher("abcdefabcdefgabcdefgh")); } }