Skip to content

Commit af188ca

Browse files
committed
hashtable-interview question
1 parent 592a2d6 commit af188ca

File tree

5 files changed

+690
-11
lines changed

5 files changed

+690
-11
lines changed

.gitignore

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ validation-report.json
4040

4141
# Folders to ignore
4242
node_modules
43+
Project-Note-PAUL
4344

4445
# Ignore all logfiles and tempfiles.
4546
!/log/.keep
4647
/tmp
4748
/.gems
4849

49-
testing-code-3.js
50-
testing-scribling-code.js
51-
testing-code-1.js
52-
testing-4.js
53-
test-5.js
54-
Cracking-The-Coding-Interview-Note-Gitignore-IT.odt
50+
random-code-1.js
51+
random-code-2.js
52+
random-code-3.js
53+
random-code-4.js
54+
performance-1.js

Hash_Table/generic_hash_table_implementation.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ class HashTable {
66
this.value = [];
77
}
88

9-
/* The Hash-function takes a key and converts it to a number which will be the index at which to store it. In my hash() function below, I am computing a hash value by summing the ASCII value of each character of the string (the argument passed-in) using the JavaScript function charCodeAt() to return a character’s ASCII value after multiplying the ASCII value by a multiplier H, which in this case, is an odd prime 37. And the reason to choose 37 being, by some empirical research, if we take over 50,000 English words (formed as the union of the word lists provided in two variants of Unix), using the constants 31, 33, 37, 39, and 41 will produce less than 7 collisions in each case, while creating a hasing function.
9+
/* The Hash-function takes a key and converts it to a number which will be the index at which to store it. In my hash() function below, I am computing a hash value by summing the ASCII value of each character of the string (the argument passed-in) using the JavaScript function charCodeAt() to return a character’s ASCII value after multiplying the ASCII value by a multiplier H, which in this case, is an odd prime 37. And the reason to choose 37 being, by some empirical research, if we take over 50,000 English words (formed as the union of the word lists provided in two variants of Unix), using the constants 31, 33, 37, 39, and 41 will produce less than 7 collisions in each case, while creating a hashing function.
1010
11-
Note that this remainder method (modulo arithmetic) will typically be present in some form in all hash functions, since the result must be in the range of slot names. In the below cae (total %= this.table.length). Because, the hash function will turn its passed-in argument and return an integer in the range of slot names, between 0 and m-1. */
11+
Note that this remainder method (modulo arithmetic) will typically be present in some form in all hash functions, since the result must be in the range of slot names. In the below cae (total %= this.table.length). Because, the hash function will turn its passed-in argument and return an integer in the range of slot names, between 0 and m-1.
12+
A perfect hash can be created if the number and construction of the keys are known factors. For example, a perfect hash for a list of ten product numbers that are sure to differ in their 4th and 5th digits can be easily constructed like so,
13+
unsigned hash(unsigned pid)
14+
{
15+
return pid / 1000 % 100;
16+
}
17+
*/
1218

1319
// the first implementation of my hash table
1420
hash(string) {
@@ -25,7 +31,7 @@ Note that this remainder method (modulo arithmetic) will typically be present in
2531
return parseInt(total);
2632
}
2733

28-
// function to console.log the distribution of the key-values. They key being the ones that were generated by the Hash Function after hashing and values what was passed in the hashing functoin as the arguments.
34+
// function to console.log the distribution of the key-values. They key being the ones that were generated by the Hash Function after hashing and values what was passed in the hashing function as the arguments.
2935
showDistro() {
3036
for (const key in this.table) {
3137
if (this.table[key] !== undefined) {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*Implement a HashMap class without using JavaScript’s built-in objects ({}) or Maps. You are provided a hash() function that takes a string and returns a number (the numbers are mostly unique, but sometimes two different strings will return the same number):
2+
3+
function hash (string) {
4+
return string
5+
.split('')
6+
.reduce((a, b) => ((a << 5) + a) + b.charCodeAt(0), 5381)
7+
}
8+
Your HashMap should support just 2 methods, get, set:
9+
10+
let map = new HashMap
11+
map.set('abc', 123) // undefined
12+
map.set('foo', 'bar') // undefined
13+
map.set('foo', 'baz') // undefined
14+
map.get('abc') // 123
15+
map.get('foo') // 'baz'
16+
map.get('def') // undefined*/
17+
18+
// hash function (provided in the problem)
19+
20+
class HashMap {
21+
constructor() {
22+
this.data = []
23+
/* Create an empty array whose each index position is a slot or bucket. So this bucket is an array of arrays. So, I will access a value in bucket, which is the inner-array
24+
bucket[indexInBucket][i] */
25+
}
26+
27+
// This hash function was already given in the original problem
28+
hash(string) {
29+
return string
30+
.split('')
31+
.reduce((a, b) => ((a << 5) + a) + b.charCodeAt(0), 5381)
32+
}
33+
34+
get(key) {
35+
let index = hash(key); // First I have to hash the given key to get the index postion in the hashtable
36+
let bucket = this.data[index];
37+
if (!bucket) {
38+
return undefined;
39+
}
40+
41+
for ([k, v] of bucket) {
42+
if (key = k) {
43+
return v;
44+
}
45+
}
46+
}
47+
48+
/*Function for storing a value in the Hash. In this the "key" is the non-hashed version of index position of the HashTable. So, I have to first get it hashed to create the actual key of the hashTable with which to store the value in the HashTable.
49+
*/
50+
set(key, value) {
51+
let index = hash(key);
52+
53+
// If the hashed-key does not exist yet then create an empty array with that hashed-key
54+
if(!this.data[index]) {
55+
this.data[index] = [];
56+
}
57+
58+
/*"bucket" is the slot or bucket at which I will store the passed-in "value" argument. */
59+
let bucket = this.data[index];
60+
let indexInBucket = 0; // Initialize the first index no to be searched in bucket with '0'
61+
62+
/*Now before storing the value at the first empty index position that is found >>
63+
Search for the bucket index position starting from zero. Implement collision-resolution.
64+
So, first check if there's any value stored at all, in bucket[indexInBucket] >> If true, then check, if this specific key is the one that was assigned to store that value.
65+
*/
66+
while (bucket[indexInBucket]) {
67+
if(bucket[indexInBucket] == key) {
68+
break
69+
}
70+
indexInBucket++
71+
}
72+
// And after I have checked for No-collision, store the value. Note that this code for storing is outside the value of the while loop.
73+
bucket[indexInBucket] = [key, value];
74+
}
75+
}
76+
77+
// Now test with some key-values -
78+
// ISSUES - I have to implemnt this test following the best practice file structure.
79+
80+
/*import { test } from 'ava'
81+
82+
test('HashMap', t => {
83+
let map = new HashMap
84+
map.set('abc', 123)
85+
map.set('foo', 'bar')
86+
map.set('foo', 'baz')
87+
t.is(map.get('abc'), 123)
88+
t.is(map.get('foo'), 'baz')
89+
t.is(map.get('def'), undefined)
90+
})*/
91+

0 commit comments

Comments
 (0)