Implementato HashCode Dictionary via LinearProbing (Open Adress) e Chaining.

This commit is contained in:
2014-05-11 22:47:12 +02:00
parent 597626b34c
commit 53d6129052
19 changed files with 961 additions and 18 deletions

View File

@@ -0,0 +1,24 @@
package dictionary;
import exceptions.InvalidEntryException;
import priorityqueue.Entry;
import java.security.InvalidKeyException;
public interface Dictionary<K,V> {
public int size();
public boolean isEmpty();
public Entry<K,V> find(K key) throws InvalidKeyException;
public Iterable<Entry<K,V>> findAll(K key) throws InvalidKeyException;
public Entry<K,V> insert(K key, V value) throws InvalidKeyException;
public Entry<K,V> remove(Entry<K, V> e) throws InvalidEntryException;
public Iterable<Entry<K,V>> entries();
}

View File

@@ -0,0 +1,192 @@
package dictionary;
import arraylist.ArrayIndexList;
import arraylist.IndexList;
import exceptions.HashExceptionKey;
import exceptions.InvalidEntryException;
import position.NodePositionList;
import position.PositionList;
import priorityqueue.Entry;
import priorityqueue.MyEntry;
import sun.rmi.log.ReliableLog;
import java.security.InvalidKeyException;
import java.util.Iterator;
/**
* Created with MONSTER.
* User: xgiovio
* Date: 11/05/2014
* Time: 19:28
*/
public class HashDictionaryChaining <K,V> implements Dictionary<K,V> {
IndexList<Logfile<K,V>> table = null;
Logfile<K,V> AVAIBLE = null;
int avaible_slots = 0;
int elements = 0;
public HashDictionaryChaining ( Logfile<K,V> IN_AVAIBLE, int in_size){
table = new ArrayIndexList<Logfile<K, V>>(in_size);
AVAIBLE = IN_AVAIBLE;
for (int i= 0 ; i< in_size ;i++){
table.add(i,AVAIBLE);
avaible_slots ++;
}
}
public float load_factor () throws InvalidKeyException{
float ret = (size() / (float)raw_size());
if ( ret >= 0.9 ) {
reformat();
return load_factor();
}
return ret;
}
public int raw_size (){
return table.size();
}
@Override
public int size() {
return elements;
}
@Override
public boolean isEmpty() {
return (size() == 0);
}
protected int hash ( K key, int size){
if ( (key instanceof String) )
return com.xgiovio.hash.functions.hash_horner( (String)key ,size );
throw new HashExceptionKey();
}
@Override
public Entry<K, V> find(K key) throws InvalidKeyException {
checkKey(key);
int h = hash(key, raw_size());
if (table.get(h) == AVAIBLE)
return null;
Logfile<K, V> n = table.get(h);
return n.find(key);
}
@Override
public Iterable<Entry<K, V>> findAll(K key) throws InvalidKeyException {
checkKey(key);
int h = hash(key,raw_size());
if (table.get(h) == AVAIBLE)
return null;
Logfile<K, V> n = table.get(h);
return n.entries();
}
@Override
public Entry<K, V> insert(K key, V value) throws InvalidKeyException {
checkKey(key);
if (load_factor() >= 0.9 )
reformat();
int h = hash(key,raw_size());
if (table.get(h) == AVAIBLE) {
Logfile<K, V> n = new Logfile<K, V>();
table.set(h,n);
avaible_slots--;
elements++;
return n.insert(key,value);
} else {
Logfile<K, V> n = table.get(h);
elements++;
return n.insert(key,value);
}
}
@Override
public Entry<K, V> remove(Entry<K, V> e) throws InvalidEntryException {
if (e == null)
throw new InvalidEntryException();
int h = hash(e.getKey(),raw_size());
if (table.get(h) == AVAIBLE)
throw new InvalidEntryException();
Logfile<K, V> n = table.get(h);
Entry<K,V> t = n.remove(e);
elements--;
if (n.size() == 0){
table.set(h,AVAIBLE);
avaible_slots++;
}
return t;
}
@Override
public Iterable<Entry<K, V>> entries() {
NodePositionList<Entry<K,V>> ret = new NodePositionList<Entry<K, V>>();
for (int i = 0 ; i< raw_size() ;i++){
if (table.get(i) != AVAIBLE){
Iterator<Entry<K,V>> local_it = table.get(i).entries().iterator();
for (;local_it.hasNext();){
ret.addLast(local_it.next());
}
}
}
return ret;
}
protected void checkKey(K key) throws InvalidKeyException {
if (key == null )
throw new InvalidKeyException("Invalid key");
}
void reformat () throws InvalidKeyException{
Iterable<Entry<K,V>> ite = entries();
int new_size = raw_size() * 2;
IndexList<Logfile<K,V>> table2 = new ArrayIndexList<Logfile<K, V>>(new_size);
avaible_slots = 0;
elements = 0;
for (int i= 0 ; i< (new_size) ;i++){
table2.add(i,AVAIBLE);
}
table = table2;
for (Entry<K,V> e : ite){
insert(e.getKey(),e.getValue());
}
}
public String toString() {
Iterator<Entry<K,V>> it = entries().iterator();
String to_return = "";
to_return = to_return + "[";
for (;it.hasNext();){
Entry<K,V> t = it.next();
if (it.hasNext()) {
to_return+=(t.toString() + " , ");
} else {
to_return+=(t.toString());
}
}
return to_return+= "]";
}
}

View File

@@ -0,0 +1,229 @@
package dictionary;
import arraylist.ArrayIndexList;
import arraylist.IndexList;
import exceptions.HashExceptionKey;
import exceptions.InvalidEntryException;
import position.NodePositionList;
import priorityqueue.Entry;
import priorityqueue.MyEntry;
import java.security.InvalidKeyException;
import java.util.Iterator;
/**
* Created with MONSTER.
* User: xgiovio
* Date: 11/05/2014
* Time: 19:28
*/
public class HashDictionaryLinearProbing<K,V> implements Dictionary<K,V> {
IndexList<Entry<K,V>> table = null;
Entry<K,V> AVAIBLE = null;
int avaible_slots = 0;
int elements = 0;
public HashDictionaryLinearProbing(Entry<K, V> IN_AVAIBLE, int in_size){
table = new ArrayIndexList<Entry<K, V>>(in_size);
AVAIBLE = IN_AVAIBLE;
for (int i= 0 ; i< in_size ;i++){
table.add(i,AVAIBLE);
avaible_slots ++;
}
}
public float load_factor () throws InvalidKeyException{
float ret = (size() / (float)raw_size());
if ( ret >= 0.5 ) {
reformat();
return load_factor();
}
return ret;
}
public int raw_size (){
return table.size();
}
@Override
public int size() {
return elements;
}
@Override
public boolean isEmpty() {
return (size() == 0);
}
protected int hash ( K key, int size){
if ( (key instanceof String) )
return com.xgiovio.hash.functions.hash_horner( (String)key ,size );
throw new HashExceptionKey();
}
@Override
public Entry<K, V> find(K key) throws InvalidKeyException {
checkKey(key);
int h = hash(key, raw_size());
int count = 0;
int i = 0;
for (;count < raw_size();){
if (table.get(h+i) == AVAIBLE)
return null;
if (table.get(h+i).getKey().equals(key))
return table.get(h+i);
i= (i + 1)% raw_size();
count++;
}
return null;
}
@Override
public Iterable<Entry<K, V>> findAll(K key) throws InvalidKeyException {
checkKey(key);
NodePositionList<Entry<K,V>> to_return = new NodePositionList<Entry<K, V>>();
int h = hash(key, raw_size());
int count = 0;
int i = 0;
for (;count < raw_size();){
if (table.get(h+i) == AVAIBLE)
return to_return;
if (table.get(h+i).getKey().equals(key))
to_return.addLast( table.get(h+i));
i= (i + 1)% raw_size();
count++;
}
return to_return;
}
@Override
public Entry<K, V> insert(K key, V value) throws InvalidKeyException {
checkKey(key);
if (load_factor() >= 0.5 )
reformat();
int h = hash(key,raw_size());
if (table.get(h) == AVAIBLE) {
MyEntry<K, V> n = new MyEntry<K, V>(key,value);
table.set(h,n);
avaible_slots--;
elements++;
return n;
} else {
int i = 1;
int count = 1;
for ( ; count < raw_size() ;) {
if (table.get(h + i) == AVAIBLE) {
MyEntry<K, V> n = new MyEntry<K, V>(key, value);
table.set(h + i, n);
avaible_slots--;
elements++;
return n;
}
i = (i + 1) % raw_size();
count++;
}
return null; // non dovresti essere qui a causa del load factor
}
}
@Override
public Entry<K, V> remove(Entry<K, V> e) throws InvalidEntryException {
if (e == null)
throw new InvalidEntryException();
int h = hash(e.getKey(),raw_size());
if (table.get(h) == AVAIBLE)
throw new InvalidEntryException();
if (table.get(h) == e) {
Entry<K, V> removed = table.get(h);
table.remove(h);
table.set(h,AVAIBLE);
elements--;
avaible_slots++;
return removed;
}
int count = 1;
for (int i = 1; count < raw_size() ; i = (i + 1) % raw_size()){
if (table.get(h + i) == AVAIBLE)
throw new InvalidEntryException();
if (table.get(h + i) == e) {
Entry<K, V> removed = table.get(h + i);
table.remove(h + i);
table.set(h + i,AVAIBLE);
elements--;
avaible_slots++;
return removed;
}
count++;
}
throw new InvalidEntryException();
}
@Override
public Iterable<Entry<K, V>> entries() {
NodePositionList<Entry<K,V>> ret = new NodePositionList<Entry<K, V>>();
for (int i = 0 ; i< raw_size() ;i++){
if (table.get(i) != AVAIBLE){
ret.addLast(table.get(i));
}
}
return ret;
}
protected void checkKey(K key) throws InvalidKeyException {
if (key == null )
throw new InvalidKeyException("Invalid key");
}
void reformat () throws InvalidKeyException{
Iterable<Entry<K,V>> ite = entries();
int new_size = raw_size() * 2;
IndexList<Entry<K,V>> table2 = new ArrayIndexList<Entry<K, V>>(new_size);
avaible_slots = 0;
elements = 0;
for (int i= 0 ; i< (new_size) ;i++){
table2.add(i,AVAIBLE);
}
table = table2;
for (Entry<K,V> e : ite){
insert(e.getKey(),e.getValue());
}
}
public String toString() {
Iterator<Entry<K,V>> it = entries().iterator();
String to_return = "";
to_return = to_return + "[";
for (;it.hasNext();){
Entry<K,V> t = it.next();
if (it.hasNext()) {
to_return+=(t.toString() + " , ");
} else {
to_return+=(t.toString());
}
}
return to_return+= "]";
}
}

131
dictionary/Logfile.java Normal file
View File

@@ -0,0 +1,131 @@
package dictionary;
import exceptions.InvalidEntryException;
import position.NodePositionList;
import position.Position;
import priorityqueue.Entry;
import priorityqueue.MyEntry;
import java.security.InvalidKeyException;
/**
* Created with MONSTER.
* User: xgiovio
* Date: 11/05/2014
* Time: 19:04
*/
public class Logfile<K,V> implements Dictionary<K,V> {
NodePositionList<Entry<K,V>> list = new NodePositionList<Entry<K,V>>();
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public Entry<K, V> find(K key) throws InvalidKeyException {
checkKey(key);
for(Position<Entry<K,V>> p: list.positions()){
Entry<K,V> e= p.element();
if(e.getKey().equals(key)){
return e;
}
}
return null;
}
@Override
public Iterable<Entry<K, V>> findAll(K key) throws InvalidKeyException {
checkKey(key);
NodePositionList<Entry<K,V>> to_return = new NodePositionList<Entry<K,V>>();
for(Position<Entry<K,V>> p: list.positions()){
Entry<K,V> e= p.element();
if(e.getKey().equals(key)){
to_return.addLast(e);
}
}
return to_return;
}
@Override
public Entry<K, V> insert(K key, V value) throws InvalidKeyException {
checkKey(key);
LocationAwareEntry<K,V> t = new LocationAwareEntry<K, V>(key,value);
list.addLast(t);
t.setLocation(list.last());
return t;
}
@Override
public Entry<K, V> remove(Entry<K, V> e) throws InvalidEntryException {
LocationAwareEntry<K,V> t = checkEntry(e);
list.remove(t.location());
t.setLocation(null);
return t;
}
@Override
public Iterable<Entry<K, V>> entries() {
return list;
}
//aux
protected void checkKey(K key) throws InvalidKeyException {
if (key == null )
throw new InvalidKeyException("Invalid key");
}
// inner class
protected static class LocationAwareEntry<K,V> extends MyEntry<K,V> {
protected Position<Entry<K, V>> loc = null;
public LocationAwareEntry(K k, V v) {
super(k, v);
}
public LocationAwareEntry(K k, V v, Position pos) {
super(k, v);
loc = pos;
}
protected Position < Entry<K,V>> location() {
return loc;
}
protected Position < Entry<K,V> >setLocation(Position< Entry<K,V>> pos) {
Position <Entry<K,V>> oldPosition = location();
loc = pos;
return oldPosition;
}
protected K setKey(K k) {
K oldKey = getKey();
key = k;
return oldKey;
}
protected V setValue(V v) {
V oldValue = getValue();
value = v;
return oldValue;
}
public String toString() { return "(" + key + "," + value + ")"; }
}
protected LocationAwareEntry<K,V> checkEntry(Entry<K,V> e) throws InvalidEntryException
{
if(e == null || !(e instanceof LocationAwareEntry) || isEmpty() )
throw new InvalidEntryException("entrata non valida");
return (LocationAwareEntry) e;
}
}