1package aud.example.hash;
4import java.util.Scanner;
29 static public class HashString
extends HashFunction<String> {
30 long m_ = 2019773507l;
32 public HashString() {}
33 public HashString(
long m) {
this(); m_=m; }
35 @Override
public long hash(String s) {
37 for (
byte b : s.getBytes()) {
38 h =(h*0x100+(b+0x80));
44 @Override
public String toString() {
45 return "HashString[m="+m_+
"]";
52 static public class IdentityHash
extends HashFunction<Integer> {
53 @Override
public long hash(Integer k) {
return k; }
54 @Override
public String toString() {
63 static public class UniversalHash
extends HashFunction<Integer> {
66 long p_ = 18014398509481951l;
68 public UniversalHash() {}
69 public UniversalHash(
long a,
long b,
long p) {
71 assert(0<a && a<p && 0<=b && b<p);
75 @Override
public long hash(Integer k) {
76 return (a_*(k>=0 ? k : -k)+b_) % p_;
78 @Override
public String toString() {
79 return "UniversalHash[a="+a_+
", b="+b_+
", p="+p_+
"]";
99 return "LinearProbing[b="+b_+
"]";
115 @Override
public long
117 return h + count*b_ + (count*count)*c_;
121 return "QuadraticProbing[b="+b_+
", c="+c_+
"]";
131 @Override
public long
133 long h2=h2_.hash(key);
134 return h+count*(h2!=0 ? h2 : 18014398509481951l);
138 return "DoubleHahsing[h2="+h2_+
"]";
151 final HashString hashstring =
new HashString();
153 public long intValue;
157 public Key(Integer i) { intValue=i; }
159 public Key(String s) { intValue=hashstring.hash(s); this.s=s; }
161 public boolean equals(Key other) {
163 (intValue==other.intValue) :
164 (s.compareTo(other.s)==0);
167 @Override
public String toString() {
168 return s!=
null ? s : (
""+intValue);
173 class HashKey
extends HashFunction<Key> {
174 HashFunction<Integer> ihash;
175 HashKey(HashFunction<Integer> hash) { this.ihash=hash; }
176 @Override
public long hash(Key k) {
return ihash.hash((
int) k.intValue); }
178 @Override
public String toString() {
179 return ihash.toString();
184 SimpleHashtable<Key> hashtable=
null;
187 HashFunction<Key> hashfunction=
new HashKey(
new IdentityHash());
190 CollisionHandler<Key> collisionhandler=
null;
193 boolean readIntegers=
true;
205 static void usage() {
207 "java HashtableExample [-m M] [-s|--string] [--timestep T]\n"+
208 " [-v | --verbose LEVEL]\n"+
209 " [-u] [--universal A B P]\n"+
210 " [-L] [--linear B]\n"+
211 " [-Q] [--quadratic B C]\n"+
212 " [-S] [--separate]\n"+
213 " [-D] [--double]\n[-h] [--help]\n\n"+
214 " The short form switches ('-' except '-m') don't take parameters,\n"+
215 " the long forms '--' require all listed parameters. (See methods\n"+
216 " for a description of parameters.)\n\n"+
217 " -s | --string forces input of strings otherwise integers are\n"+
219 " --timestep set timestep for recording history\n"+
220 " -v | --verbose print additonal information\n"+
221 " The default hash function is modulo table size M (default M=11).\n"+
222 " -u | --universal select the universal has function\n\n"+
223 " -L,-Q,-S select linear probing, quadratic probing, or separate\n"+
224 " chaining (default)\n"+
225 " -D selects double hashing, any subsequent -u | --universal modifies\n"+
226 " the secondary hash function, which should be specified\n"+
227 " differently from the primal hash function! (No checks!)\n\n"+
228 " -h | --help displays this message\n\n"+
229 "The program reads from standard input and inserts integers/words to\n"+
230 "into the hash table.\n"+
231 "The following \"words\" have a special meaning:\n"+
233 " '?' prints the contents of the hash table to standard output\n"+
234 " '!' visualizes the history of the hash table in a new window\n\n"
240 public HashtableExample(String args[]) {
243 HashFunction<Integer> h2=
new IdentityHash();
244 boolean haveDoubleHashing=
false;
246 for (
int i=0;i<args.length;++i) {
247 if (args[i].compareTo(
"-m")==0)
248 m=Integer.parseInt(args[++i]);
249 else if (args[i].compareTo(
"--timestep")==0)
250 timestep=Integer.parseInt(args[++i]);
251 else if (args[i].compareTo(
"-v")==0)
253 else if (args[i].compareTo(
"--verbose")==0)
254 verbose=Integer.parseInt(args[++i]);
255 else if (args[i].compareTo(
"--string")==0 || args[i].compareTo(
"-s")==0)
257 else if (args[i].compareTo(
"--help")==0 || args[i].compareTo(
"-h")==0)
259 else if (args[i].compareTo(
"-u")==0)
260 hashfunction=
new HashKey(
new UniversalHash());
261 else if (args[i].compareTo(
"--universal")==0) {
262 HashFunction<Integer> h=
264 Integer.parseInt(args[++i]),
265 Integer.parseInt(args[++i]),
266 Integer.parseInt(args[++i])
268 if (haveDoubleHashing)
271 hashfunction=
new HashKey(h);
273 else if (args[i].compareTo(
"--separate")==0 || args[i].compareTo(
"-S")==0)
274 collisionhandler=
null;
275 else if (args[i].compareTo(
"-L")==0)
276 collisionhandler=
new LinearProbing<Key>();
277 else if (args[i].compareTo(
"--linear")==0)
278 collisionhandler=
new LinearProbing<Key>(Integer.parseInt(args[++i]));
279 else if (args[i].compareTo(
"-Q")==0)
280 collisionhandler=
new QuadraticProbing<Key>();
281 else if (args[i].compareTo(
"--quadratic")==0)
282 collisionhandler=
new QuadraticProbing<Key>
283 (Integer.parseInt(args[++i]),Integer.parseInt(args[++i]));
284 else if (args[i].compareTo(
"--double")==0 || args[i].compareTo(
"-D")==0) {
285 haveDoubleHashing=
true;
286 collisionhandler=
null;
292 if (haveDoubleHashing)
293 collisionhandler=
new DoubleHashing<Key>(
new HashKey(h2));
296 System.err.println(
"> hash table with m="+m);
297 System.err.println(
"> hash function="+hashfunction);
298 System.err.println(
"> collision handling="+
299 (collisionhandler==
null ?
300 "separate chaining" : collisionhandler.toString()
303 System.err.println(
"> reading integers...\n");
305 System.err.println(
"> reading strings (HashString)...\n");
307 hashtable=
new SimpleHashtable<Key>(m,hashfunction,collisionhandler);
308 hashtable.verbose=(verbose>0);
312 public void start() {
313 SVGViewer viewer=
null;
315 hashtable.beginRecording();
317 Scanner s=
new Scanner(System.in);
318 s.useDelimiter(
"\\s+");
320 while (s.hasNext()) {
322 if (key.startsWith(
"."))
324 else if (key.startsWith(
"?")) {
325 if (key.startsWith(
"?svg:")) {
326 hashtable.history_.renderSpySVG(
327 new File(key.substring(5)+
".svg"),
new ColormapCount());
329 else if (key.startsWith(
"?tikz"))
330 System.out.println(hashtable
331 .history_.spyTikZ(
true,
new ColormapCount()));
333 System.out.println(hashtable);
335 else if (key.startsWith(
"!")) {
338 viewer=hashtable.showHistory();
341 Key k=readIntegers ?
new Key(Integer.parseInt(key)) : new Key(key);
342 if ((time++)%timestep==0)
343 hashtable.nextTimeStep();
350 viewer=hashtable.showHistory();
356 public static void main(String args[]) {
357 new HashtableExample(args).start();
Collision handling strategy in SimpleHashtable.
interface for a hash function
Collision handling by double hashing using h2
long newHash(SimpleHashtable< T > table, T key, long h, int count)
Handle collision by computing a new hash value.
DoubleHashing(HashFunction< T > h2)
Collision handling by linear probing h(x,i)=h(x)+i*b
long newHash(SimpleHashtable< T > table, T key, long h, int count)
Handle collision by computing a new hash value.
Collision handling by quadratic probing h(x,i)=h(x)+i*b+i*i*c
long newHash(SimpleHashtable< T > table, T key, long h, int count)
Handle collision by computing a new hash value.
QuadraticProbing(int b, int c)
Simple framework for experiments with hash tables.
Base class for simple hash tables (mainly for demonstration).
color map for (small) positive integer counts
Simple SVG viewer based on Batik's SVGCanvas.
utilities (not related to AuD lecture)
AuD lecture: Data structures, algorithms, examples.