-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
check driver for important notes
- Loading branch information
UsefSaeed
authored and
UsefSaeed
committed
May 12, 2022
1 parent
ebbcda6
commit 06cab6b
Showing
4 changed files
with
243 additions
and
9 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
public class Driver { | ||
public static void main(String[] args){ | ||
int[] a = {12,21,32,43,4,5,3,356,3224,54,455}; | ||
PerfectHashing.Method1 m1 = new PerfectHashing.Method1(a); | ||
PerfectHashing.Method2 m2 = new PerfectHashing.Method2(a); | ||
/** | ||
* MONO DO YOUR THING (ANALYSIS) | ||
*/ | ||
} | ||
} | ||
/** | ||
* Important Notes: | ||
* 1. Turned out that collision may happen in perfect hashing method2 for some reason | ||
* 1.1. Realised that though testing | ||
* 1.2. Used method1 code (still incomplete) in method2 perfectRehash() after figuring out all collisions | ||
* 1.3. Once the mainLogic() in method1 works perfectly, method2 also works perfectly | ||
* 1.3.1. finalHashTable includes all elements passed to method1 as well as zeros in null places | ||
* 1.3.2. hashMatrix includes matrix used to get the element's keys | ||
* 2. Method2 is fully tested (not including the method1 part for sure) | ||
* 3. If no collision takes place in method2, method1 is not used. So, testcase runs successfully | ||
* 4. Don't forget the search() in method1 because I was about to, lol | ||
* 5. Running the same testcase several times will produce different outcome due to randomization | ||
* 5.1. may make debugging certain cases really difficult as some runs may work and others not | ||
* 6. I'll sleep at 4-5 am and wake up at 12 pm, be free at 1-6 pm | ||
* 7. Yeah. I also added some methods from method2 you will need in method1, some getters and attributes that are also needed | ||
* GOODLUCK BRO | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,61 @@ | ||
package PerfectHashing; | ||
|
||
import java.util.Random; | ||
|
||
public class Method1 { | ||
private int[] input; | ||
private int size; | ||
private final int[] input; | ||
private final int size; | ||
private int[] hashMatrix; | ||
private int[] finalHashTable; | ||
|
||
public Method1(int[] input) { | ||
this.input = input; | ||
this.size = input.length*input.length; | ||
this.size = input.length; | ||
this.hashMatrix = generateHashMatrix(this.size*this.size); | ||
this.finalHashTable = new int[this.size*this.size]; | ||
this.mainLogic(); | ||
} | ||
|
||
int[] generateHashMatrix(){ | ||
int[] generateHashMatrix(int size){ | ||
int[] res = new int[size]; | ||
return res; | ||
Random rand = new Random(); | ||
for (int i=0; i<size;i++) | ||
res[i] = rand.nextInt(Integer.MAX_VALUE); | ||
return res; | ||
} | ||
|
||
int getKey(int[] h,int x){ | ||
int key=0; | ||
int size = h.length; | ||
for (int i = 0; i < size; i++){ | ||
key=key<<1; | ||
key |= parity(x & h[i]); | ||
} | ||
return key%size; | ||
} | ||
|
||
int parity(int p){ | ||
int isOdd=0; | ||
while(p!=0){ | ||
isOdd ^= 1; | ||
p &= p-1; | ||
} | ||
return isOdd; | ||
} | ||
|
||
void mainLogic(){ | ||
/** | ||
* MONO DO YOUR THING | ||
*/ | ||
} | ||
|
||
|
||
|
||
public int[] getFinalHashTable() { | ||
return finalHashTable; | ||
} | ||
|
||
public int[] getHashMatrix() { | ||
return hashMatrix; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,125 @@ | ||
package PerfectHashing; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Random; | ||
|
||
public class Method2 { | ||
private int[] input; | ||
private int size; | ||
private final int[] input; | ||
private final int[] mainHashMatrix; | ||
private int[] hashLvl1; | ||
private final int[][] hashMatricesLvl2; | ||
private final int[][] hashLvl2; | ||
private final int size; | ||
private boolean usedLvl2; | ||
|
||
public Method2(int[] input) { | ||
this.input = input; | ||
this.size = input.length; | ||
this.hashLvl1 = new int[this.size]; | ||
this.mainHashMatrix = generateHashMatrix(this.size); | ||
this.hashMatricesLvl2 = new int[this.size][]; | ||
this.hashLvl2 = new int[this.size][]; | ||
this.usedLvl2 = false; | ||
this.hashPerfectionist(); | ||
} | ||
|
||
int[] generateHashMatrix(){ | ||
int[] generateHashMatrix(int size){ | ||
int[] res = new int[size]; | ||
Random rand = new Random(); | ||
for (int i=0; i<size;i++) | ||
res[i] = rand.nextInt(Integer.MAX_VALUE); | ||
return res; | ||
} | ||
|
||
int getKey(int[] h,int x){ | ||
int key=0; | ||
int size = h.length; | ||
for (int i = 0; i < size; i++){ | ||
key=key<<1; | ||
key |= parity(x & h[i]); | ||
} | ||
return key%size; | ||
} | ||
|
||
int parity(int p){ | ||
int isOdd=0; | ||
while(p!=0){ | ||
isOdd ^= 1; | ||
p &= p-1; | ||
} | ||
return isOdd; | ||
} | ||
|
||
void hashPerfectionist(){ | ||
if (!doneByLvl1()) perfectRehash(); | ||
} | ||
|
||
boolean doneByLvl1(){ | ||
boolean[] beenHereBefore = new boolean[size]; | ||
for (int i=0;i<size;i++){ | ||
int key = getKey(mainHashMatrix,input[i]); | ||
if (beenHereBefore[key]) return false; | ||
beenHereBefore[key] = true; | ||
hashLvl1[key] = input[i]; | ||
} | ||
return true; | ||
} | ||
|
||
void perfectRehash(){ | ||
usedLvl2 = true; | ||
hashLvl1 = new int[size]; | ||
boolean[] beenHereBefore = new boolean[size]; | ||
ArrayList[] collisionCont = new ArrayList[size]; | ||
for (int i=0;i<size;i++){ | ||
int key = getKey(mainHashMatrix,input[i]); | ||
hashLvl1[key]++; | ||
if (!beenHereBefore[key]) | ||
collisionCont[key] = new ArrayList<Integer>(); | ||
beenHereBefore[key] = true; | ||
collisionCont[key].add(input[i]); | ||
} | ||
for (int i=0;i<size;i++){ | ||
int collisionsNum = hashLvl1[i]; | ||
if (collisionsNum==0) continue; | ||
int newHashSize = collisionsNum*collisionsNum; | ||
hashMatricesLvl2[i] = generateHashMatrix(newHashSize); | ||
hashLvl2[i] = new int[newHashSize]; | ||
if (newHashSize==1){ | ||
hashLvl2[i][0] = (int) collisionCont[i].get(0); | ||
continue; | ||
} | ||
int[] lvl2CurrentBlock = convertToArray((ArrayList<Integer>) collisionCont[i]); | ||
Method1 m = new Method1(lvl2CurrentBlock); | ||
hashLvl2[i] = m.getFinalHashTable(); | ||
hashMatricesLvl2[i] = m.getHashMatrix(); | ||
} | ||
|
||
} | ||
|
||
int[] convertToArray(ArrayList<Integer> a){ | ||
int[] b = new int[a.size()]; | ||
int i=0; | ||
for (int elem : a) b[i++] = elem; | ||
return b; | ||
} | ||
|
||
void search(int rtf){ | ||
int key1 = getKey(mainHashMatrix,rtf); | ||
boolean found = false; | ||
if(!usedLvl2){ | ||
if (hashLvl1[key1]==rtf) found = true; | ||
}else{ | ||
int key2 = getKey(hashMatricesLvl2[key1],rtf); | ||
if (hashLvl2[key1][key2]==rtf) found = true; | ||
} | ||
if (found) | ||
System.out.print("Found it :)"); | ||
else | ||
System.out.print("It doesn't exist :("); | ||
} | ||
|
||
// public static void main(String[] args){ | ||
// int[] a = {12,21,32,43,4,5,3,356,3224,54,455}; | ||
// Method2 m = new Method2(a); | ||
// } | ||
} |