mirror of
https://github.com/tu-darmstadt-informatik/AuD18.git
synced 2025-12-13 09:55:49 +00:00
Started implementing HashTable class
This commit is contained in:
parent
37b7b83e87
commit
b03f39a8e5
1
HashTable/.gitignore
vendored
Normal file
1
HashTable/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/bin/
|
||||||
@ -1,5 +1,9 @@
|
|||||||
package lab;
|
package lab;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import frame.Entry;
|
import frame.Entry;
|
||||||
@ -15,6 +19,13 @@ import frame.Entry;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class HashTable {
|
public class HashTable {
|
||||||
|
|
||||||
|
private int capacity;
|
||||||
|
private int hashFunction; // 0: division, 1: folding, 2: mid_square
|
||||||
|
private int probingMode; // 0: linear, 1: quadratic
|
||||||
|
|
||||||
|
private Entry[] data;
|
||||||
|
private int valueCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor
|
* The constructor
|
||||||
@ -33,9 +44,11 @@ public class HashTable {
|
|||||||
* assume a bucket factor of 1.
|
* assume a bucket factor of 1.
|
||||||
*/
|
*/
|
||||||
public HashTable(int k, String hashFunction, String collisionResolution) {
|
public HashTable(int k, String hashFunction, String collisionResolution) {
|
||||||
/**
|
this.data = new Entry[k];
|
||||||
* Add your code here
|
this.hashFunction = 0; // TODO
|
||||||
*/
|
this.probingMode = collisionResolution.equals("quadratic_probing") ? 1 : 0;
|
||||||
|
this.valueCount = 0;
|
||||||
|
this.capacity = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,10 +66,29 @@ public class HashTable {
|
|||||||
* Hash-Table.
|
* Hash-Table.
|
||||||
*/
|
*/
|
||||||
public int loadFromFile(String filename) {
|
public int loadFromFile(String filename) {
|
||||||
/**
|
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
|
||||||
* Add your code here
|
String line;
|
||||||
*/
|
String[] parts;
|
||||||
return 0;
|
int insertionCount = 0;
|
||||||
|
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
parts = line.split(";");
|
||||||
|
Entry entry = new Entry(parts[0], parts[1], parts[2]);
|
||||||
|
|
||||||
|
if(this.insert(entry))
|
||||||
|
insertionCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(insertionCount);
|
||||||
|
|
||||||
|
return insertionCount;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("File not found");
|
||||||
|
return 0;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("IO Exception");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,10 +104,28 @@ public class HashTable {
|
|||||||
* if the entry already exists in the Hash-Table
|
* if the entry already exists in the Hash-Table
|
||||||
*/
|
*/
|
||||||
public boolean insert(Entry insertEntry) {
|
public boolean insert(Entry insertEntry) {
|
||||||
/**
|
int address = this.getHashAddr(insertEntry);
|
||||||
* Add your code here
|
int base = address;
|
||||||
*/
|
int i = 1;
|
||||||
return false;
|
while(this.data[address] != null && !this.data[address].isDeleted()) {
|
||||||
|
if(i > this.capacity || this.data[address].getKey().equals(insertEntry.getKey()))
|
||||||
|
return false;
|
||||||
|
address = this.getProbingAddr(base, i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.data[address] == null)
|
||||||
|
this.valueCount += 1;
|
||||||
|
|
||||||
|
this.data[address] = insertEntry;
|
||||||
|
|
||||||
|
// Trigger rehash if load factor > 0.75
|
||||||
|
if(((double) this.valueCount) / this.capacity > 0.75)
|
||||||
|
this.rehash();
|
||||||
|
|
||||||
|
System.out.println("Load: "+Double.toString(((double) this.valueCount) / this.capacity));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,10 +139,22 @@ public class HashTable {
|
|||||||
* the entry is not found in the Hash-Table
|
* the entry is not found in the Hash-Table
|
||||||
*/
|
*/
|
||||||
public Entry delete(String deleteKey) {
|
public Entry delete(String deleteKey) {
|
||||||
/**
|
int address = this.getHashAddr(deleteKey);
|
||||||
* Add your code here
|
int base = address;
|
||||||
*/
|
int i = 1;
|
||||||
return null;
|
while(this.data[address] != null && !this.data[address].getKey().equals(deleteKey)) {
|
||||||
|
if(i > this.capacity)
|
||||||
|
return null;
|
||||||
|
address = this.getProbingAddr(base, i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.data[address] != null) {
|
||||||
|
this.data[address].markDeleted();
|
||||||
|
return this.data[address];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,10 +168,17 @@ public class HashTable {
|
|||||||
* null if the entry is not found in the Hash-Table
|
* null if the entry is not found in the Hash-Table
|
||||||
*/
|
*/
|
||||||
public Entry find(String searchKey) {
|
public Entry find(String searchKey) {
|
||||||
/**
|
int address = this.getHashAddr(searchKey);
|
||||||
* Add your code here
|
int base = address;
|
||||||
*/
|
int i = 1;
|
||||||
return null;
|
while(this.data[address] != null && !this.data[address].getKey().equals(searchKey)) {
|
||||||
|
if(i > this.capacity)
|
||||||
|
return null;
|
||||||
|
address = this.getProbingAddr(base, i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.data[address].isDeleted() ? null : this.data[address];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,11 +190,44 @@ public class HashTable {
|
|||||||
* @return returns the output Hash-Table in directly interpretable dot code
|
* @return returns the output Hash-Table in directly interpretable dot code
|
||||||
*/
|
*/
|
||||||
public ArrayList<String> getHashTable() {
|
public ArrayList<String> getHashTable() {
|
||||||
/**
|
ArrayList<String> dot = new ArrayList<String>();
|
||||||
* Add your code here
|
dot.add("digraph {");
|
||||||
*/
|
dot.add("splines=true;");
|
||||||
return null;
|
dot.add("nodesep=.01;");
|
||||||
|
dot.add("rankdir=LR;");
|
||||||
|
dot.add("node[fontsize=8,shape=record,height=.1;]");
|
||||||
|
String addressdef = "[fontsize=12,label=\"";
|
||||||
|
for(int i = 0; i < this.capacity; i++) {
|
||||||
|
addressdef += "<f"+Integer.toString(i)+">"+Integer.toString(i)+(i < this.capacity - 1 ? "|" : "");
|
||||||
|
}
|
||||||
|
addressdef += "\"];";
|
||||||
|
dot.add(addressdef);
|
||||||
|
|
||||||
|
int j = 1;
|
||||||
|
for(int i = 0; i < this.capacity; i++) {
|
||||||
|
if(this.data[i] != null) {
|
||||||
|
String insertSequence = getInsertionSequence(this.data[i].getKey());
|
||||||
|
String line = "node"+Integer.toString(j)+"[label=\"{<l>" + this.data[i].getKey() + '|' + this.data[i].getData() + insertSequence + "}\"];";
|
||||||
|
dot.add(line);
|
||||||
|
System.out.println(line);
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 1;
|
||||||
|
for(int i = 0; i < this.capacity; i++) {
|
||||||
|
if(this.data[i] != null) {
|
||||||
|
String line = "ht:f"+Integer.toString(i)+"->node" + Integer.toString(j) + ":l;";
|
||||||
|
dot.add(line);
|
||||||
|
System.out.println(line);
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dot.add("}");
|
||||||
|
return dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method increases the capacity of the Hash-Table and reorganizes it, in
|
* This method increases the capacity of the Hash-Table and reorganizes it, in
|
||||||
@ -137,8 +239,82 @@ public class HashTable {
|
|||||||
* increased to 1009, which is the closest primary number less than (101*10).
|
* increased to 1009, which is the closest primary number less than (101*10).
|
||||||
*/
|
*/
|
||||||
private void rehash() {
|
private void rehash() {
|
||||||
/**
|
|
||||||
* Add your code here
|
System.out.println("REHASH");
|
||||||
*/
|
|
||||||
|
int newSize = this.capacity * 10;
|
||||||
|
|
||||||
|
while(!isPrime(newSize)) {
|
||||||
|
newSize -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(newSize);
|
||||||
|
|
||||||
|
int oldSize = this.capacity;
|
||||||
|
Entry[] oldData = this.data;
|
||||||
|
|
||||||
|
this.data = new Entry[newSize];
|
||||||
|
this.capacity = newSize;
|
||||||
|
|
||||||
|
for(int i = 0; i < oldSize; i++) {
|
||||||
|
if(oldData[i] != null && !oldData[i].isDeleted()) {
|
||||||
|
this.insert(oldData[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long decimalRepresentation(String value) {
|
||||||
|
char[] key = value.toCharArray();
|
||||||
|
String str = Integer.toString((int) key[0]) + Integer.toString((int) key[1]) + Integer.toString((int) key[2]) + Integer.toString((int) key[3]) + Integer.toString((int) key[4]);
|
||||||
|
return Long.parseLong(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getHashAddr(Entry value) {
|
||||||
|
return this.getHashAddr(value.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getHashAddr(String key) {
|
||||||
|
if(this.hashFunction == 0)
|
||||||
|
return this.divisionHash(key);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int divisionHash(String value) {
|
||||||
|
long decimal = decimalRepresentation(value);
|
||||||
|
return Math.toIntExact(decimal % this.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getProbingAddr(int base, int i) {
|
||||||
|
if(this.probingMode == 0)
|
||||||
|
return (base + i) % this.capacity;
|
||||||
|
else {
|
||||||
|
int nextTry = ((int)(base - Math.ceil(Math.pow(((float) i)/2, 2))*Math.pow(-1, i))) % this.capacity;
|
||||||
|
return nextTry < 0 ? nextTry + this.capacity : nextTry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInsertionSequence(String searchKey) {
|
||||||
|
int address = this.getHashAddr(searchKey);
|
||||||
|
int base = address;
|
||||||
|
int i = 1;
|
||||||
|
String sequence = "";
|
||||||
|
while(this.data[address] != null && !this.data[address].getKey().equals(searchKey)) {
|
||||||
|
sequence += Integer.toString(address) + ", ";
|
||||||
|
address = this.getProbingAddr(base, i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sequence.length() > 2 ? "|" + sequence.substring(0, sequence.length() - 2) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPrime(int p) {
|
||||||
|
int i = 2;
|
||||||
|
while(i <= Math.sqrt(p)) {
|
||||||
|
if(p % i == 0)
|
||||||
|
return false;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user