0% found this document useful (0 votes)
18 views5 pages

Hashing Mastery Guide

The document is a comprehensive guide on hashing techniques, covering various methods such as modular arithmetic, collision handling, and different hashing strategies like separate chaining and open addressing. It includes practical code examples for operations like insertion, deletion, and searching, along with advanced concepts like polynomial hashing and rolling hash. Additionally, it provides tips for optimizing hashing performance and minimizing collisions.

Uploaded by

Bias Hacker
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views5 pages

Hashing Mastery Guide

The document is a comprehensive guide on hashing techniques, covering various methods such as modular arithmetic, collision handling, and different hashing strategies like separate chaining and open addressing. It includes practical code examples for operations like insertion, deletion, and searching, along with advanced concepts like polynomial hashing and rolling hash. Additionally, it provides tips for optimizing hashing performance and minimizing collisions.

Uploaded by

Bias Hacker
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

HASHING MASTERY GUIDE

Time to unlock the secrets of HASHING. 🔥


We’re going deep into modular arithmetic, collision handling, double hashing, rolling hash,
perfect hash, polynomial hash — everything a Codeforces grandmaster would know. Let’s
build you into a Hashing GOD:

1. What is Hashing?
Hashing is a method to map data to a fixed-size value (hash). Uses a hash function to map
keys to a fixed-size table.
Efficient for insertion, deletion, and search — average time complexity is O(1).

2. Key Hashing Operations


Insert O(1)
➡️
Delete O(1)
➡️
Search O(1)
➡️
Handle collisions Chaining, Open Addressing
➡️
Efficient hashing Minimize collisions
➡️

3. Direct Addressing
Simple array-based mapping. Only works if keys are small and non-negative integers.

int table[1000] = {0};

void insert(int key) {


table[key] = 1;
}

bool search(int key) {


return table[key] == 1;
}

void remove(int key) {


table[key] = 0;
}

4. Separate Chaining (Linked List)

const int MOD = 10007;


vector<int> table[MOD];
void insert(int key) {
int h = key % MOD;
table[h].push_back(key);
}

bool search(int key) {


int h = key % MOD;
for (int x : table[h]) if (x == key) return true;
return false;
}

void remove(int key) {


int h = key % MOD;
table[h].erase(remove(table[h].begin(), table[h].end(), key), table[h].end());
}

5. Open Addressing (Linear Probing)

const int MOD = 10007;


int table[MOD];

void insert(int key) {


int h = key % MOD;
while (table[h] != 0) h = (h + 1) % MOD;
table[h] = key;
}

bool search(int key) {


int h = key % MOD;
while (table[h] != 0) {
if (table[h] == key) return true;
h = (h + 1) % MOD;
}
return false;
}

void remove(int key) {


int h = key % MOD;
while (table[h] != 0) {
if (table[h] == key) {
table[h] = -1;
return;
}
h = (h + 1) % MOD;
}
}

6. Double Hashing

const int MOD = 10007;


int table[MOD];

int h2(int key) {


return 1 + (key % (MOD - 1));
}

void insert(int key) {


int h = key % MOD;
int step = h2(key);
while (table[h] != 0) h = (h + step) % MOD;
table[h] = key;
}

bool search(int key) {


int h = key % MOD;
int step = h2(key);
while (table[h] != 0) {
if (table[h] == key) return true;
h = (h + step) % MOD;
}
return false;
}

7. Polynomial Hashing

const int P = 31;


const int MOD = 1e9 + 9;

long long hashString(string s) {


long long hash = 0, p_pow = 1;
for (char c : s) {
hash = (hash + (c - 'a' + 1) * p_pow) % MOD;
p_pow = (p_pow * P) % MOD;
}
return hash;
}

8. Rolling Hash

const int P = 31;


const int MOD = 1e9 + 9;

vector<long long> precomputeHash(string s) {


int n = s.size();
vector<long long> hash(n + 1, 0), power(n + 1, 1);

for (int i = 1; i <= n; i++) {


power[i] = (power[i - 1] * P) % MOD;
hash[i] = (hash[i - 1] + (s[i - 1] - 'a' + 1) * power[i - 1]) % MOD;
}

return hash;
}

long long substringHash(int l, int r, vector<long long>& hash, vector<long long>& power) {
long long h = (hash[r + 1] - hash[l] + MOD) % MOD;
h = (h * power[100000 - l]) % MOD;
return h;
}

9. Perfect Hashing (Minimal Collision)

const int P = 99999989;


const int MOD = 10007;
int a = 31, b = 53;

int perfectHash(int key) {


return ((a * key + b) % P) % MOD;
}

10. Tips from Grandmasters


🔥 Always use a prime modulus — reduces collisions.
🔥 Use double hashing when collisions are too high.
🔥 For string matching, use rolling hash over KMP for faster implementation.
🔥 Use Z-Function + Polynomial Hash for the most efficient string matching.
🔥 To avoid overflow, use unsigned long long or __int128.
🔥 Try using hashmaps over arrays for dynamic input sizes.

You might also like