/************************************************************* file: hash1.c (Variation of hash.c) Fundamental Algorithms, Spring 2003, Yap. Programmed by T.A. I.Chikanian. Note: This program writes to the output file "hash1.txt" It produce the answers for Homework 5, Question 4 on Hashing. (a) Computes the first 60 values of hashing golden ratio (g=1.618...) to the unit interval: {g}, {2g}, {3g},..., {60g} (b) It tracks the distant interval lengths that are produced by (a) (c) It compute the hashed table for hashing 16 items using multiplication method (d) Same as (c) but for division method *************************************************************/ #include "stdio.h" #include "math.h" int find(float r, float l[100], int il); float find_pred(float r, float h[100], int n); float find_succ(float r, float h[100], int n); int hash1(const char word[3]); int hash2(const char word[3]); int num26(const char word[3]); int code26(char c); // float g = (1.0 + sqrt(5))/2.0; // golden ratio float g; int main(int argc, char* argv[]) { int i, k; float f[100], r[100]; float l[100]; // stores the new lengths of intervals l[0] = 0.0; // l[0] is the initial length l[1] = 1.0; // l[0] is the initial length int il = 2; // index into array l[], // l[il] is the next unused entry. float pred, succ, new1, new2; char* data[] = {" ", // this is for data[0] "AND","ARE"," AS"," AT"," BE","BOY","BUT"," BY", "FOR","HAD","HER","HIS","HIM"," IN"," IS"," IT"}; FILE* pf = fopen("hash1.txt","w"); // g = (1.0 + sqrt(5))/2.0; // golden ratio g = sqrt(2); // different ratio fprintf(pf, "(a) First 60 numbers and lengths they created (new1,new2)\n"); fprintf(pf, "------------------------------------------------------------------\n"); for (i=1; i<=60; i++) { f[i] = i*g; // this is full i*g k = f[i]; // this is floor(i*g) r[i] = f[i] - k; // this is {i*g} = i*g - floor(i*g) pred = find_pred(r[i],r,i); succ = find_succ(r[i],r,i); new1 = r[i] - pred; new2 = succ - r[i]; if (new1 > new2) { if (find(new1, l, il) <0) l[il++] = new1; if (find(new2, l, il) <0) l[il++] = new2; } else { if (find(new2, l, il) <0) l[il++] = new2; if (find(new1, l, il) <0) l[il++] = new1; } fprintf(pf, "i=%2d, f=%7.4f, k=%2d, r=%5.4f, new1=%5.4f, new2=%5.4f\n", i, f[i], k, r[i], new1, new2); } fprintf(pf, "\n (b) Distinct lengths created by the first 60 insertions \n"); fprintf(pf, "------------------------------------------------------------------\n"); for (i=1; i< il; i++){ fprintf(pf, "i = %2d, Length = %5.4f\n", i, l[i]); } fprintf(pf, "\n(c) Hashing 16 data items by multiplication, m=10\n"); fprintf(pf, "------------------------------------------------------\n"); for (i=1;i<=16;i++) { fprintf(pf, "i=%2d, data=%s, num=%5d, slot=%2d\n", i, data[i], num26(data[i]), hash1(data[i])); } fprintf(pf, "\n(d) Hashing 16 data items by division, m=17\n"); fprintf(pf, "------------------------------------------------------\n"); for (i=1;i<=16;i++) { fprintf(pf, "i=%2d, data=%s, num=%5d, slot=%2d\n", i, data[i], num26(data[i]), hash2(data[i])); } fclose(pf); return 0; } float find_pred(float r, float h[100], int n) { /* finds a proper predecessor of r in array h */ int i; float curr_pred = 0.0; for (i=1; i<=n; i++) { if ((h[i]r)&&(curr_succ>h[i])) curr_succ = h[i]; } return curr_succ; } // returns index x where r=l[x] if r is in l[0,..,il] // returns -1 else int find(float r, float l[100], int il) { int i, pred = 0, succ = -1; float pred_val=0.0, succ_val = 1.0; for (i=1; i= l[i] )&&(l[i] > pred_val)) { pred_val = l[i]; pred = i; } } if (pred == succ) return pred; return -1; } int hash1(const char word[3]) { int k,i; float f,r; k = num26(word); f = k*g; // this is full k*g i = f; // this is floor(k*g) r = f - i; // this is {k*g} = k*g - floor(k*g) return 10*r; // this is floor(m*{k*g}), m=10 } int hash2(const char word[3]) { int k; k = num26(word); return (k % 17); // here m=17 } int num26(const char word[3]) { return (26 * 26 * code26(word[0])) + (26 * code26(word[1])) + code26(word[2]); } int code26(char c) { if (c==' ') return 0; else return c-64; }