homedukeAlgorithmen & Datenstrukturen mit Java: Beispielklasse für einfache Hash-Tabellen Prof. Dr. Uwe Schmidt FH Wedel

Beispielklasse für einfache Hash-Tabellen

weiter

weiter

Map
Schnittstelle bleibt unverändert
weiter
   1package ds.interfaces;
   2
   3/** Simple interface for maps
   4 */
   5
   6import java.util.Iterator;
   7
   8import ds.util.Invariant;
   9import ds.util.Function2;
  10
  11import ds.util.K;  // example class for keys
  12import ds.util.V;  // example class for values
  13import ds.util.KV// key value pair
  14
  15public
  16    interface Map
  17    extends Iterable<KV>,
  18            Invariant {
  19
  20    boolean isEmpty();
  21    boolean member(K k);
  22    V       lookup(K k);
  23    int     size();
  24    KV      findMin();
  25    KV      findMax();
  26    Map     insert(K kV v);
  27    Map     remove(K k);
  28    Map     union(Map m2);
  29    Map     difference(Map m2);
  30    Map     unionWith(Function2<V,V,V> opMap m2);
  31    Map     differenceWith(Function2<V,V,V> opMap m2);
  32    Map     copy();
  33
  34    // inherited
  35
  36    // public Iterator<KV> iterator();
  37    // public inv();
  38}
weiter
Map
implementiert als sehr einfache Hash-Tabelle
ohne Generics
nur eine destruktive Implementierung ist hier sinnvoll
weiter
   1package ds.destructive.map;
   2
   3/** Implementation of maps with hash maps implemeted as arrays
   4
   5    hash maps require a a hash function on the
   6    keys of a map. These hashes are used for indexing the
   7    hash table.
   8
   9    This is a DESTRUCTIVE implementation.
  10*/
  11
  12import ds.interfaces.Map;
  13
  14import ds.util.K;  // example class for keys
  15import ds.util.V;  // example class for values
  16import ds.util.KV// key value pair
  17import static ds.util.KV.mkPair;
  18
  19import ds.util.Function2;
  20import ds.util.Invariant;
  21import ds.util.Pair;
  22import ds.util.Predicate;
  23
  24import java.util.Iterator;
  25
  26import static ds.util.Undef.undefined;
  27
  28//----------------------------------------
  29
  30public
  31    class SimpleHashMap
  32    implements Map {
  33
  34    //----------------------------------------
  35
  36    private int     card;
  37    private KV []  elems;
  38
  39    SimpleHashMap (int len) {
  40        card   = 0;
  41        elems  = new KV [len];
  42        ++cntMap;
  43    }
  44
  45    //----------------------------------------
  46    // the smart constructors
  47
  48    // empty list
  49    public static SimpleHashMap empty() {
  50        return
  51            empty(16)// why 16?
  52    }
  53
  54    public static SimpleHashMap empty(int length) {
  55        int l = 16;
  56        while (l < length) l *= 2;
  57
  58        // length of hash table is always a power of 2
  59        // for efficient modulo operations
  60
  61        return
  62            new SimpleHashMap(length);
  63    }
  64
  65    public static
  66        SimpleHashMap fromIterator(Iterator<KV> elems) {
  67
  68        SimpleHashMap res = empty();
  69        while ( elems.hasNext() ) {
  70            KV p = elems.next();
  71            res  = res.insert(p);
  72        }
  73        return
  74            res;
  75    }
  76
  77    public boolean isEmpty() {
  78        return size() == 0;
  79    }
  80
  81    public boolean member(K k) {
  82        return
  83            lookup(k) != null;
  84    }
  85
  86    public int size() {
  87        return
  88            card;
  89    }
  90
  91    public V lookup(K k) {
  92        int ix = keyToHash(k);
  93        KV  kv = elems[ix];
  94
  95        while ( kv != null
  96                &&
  97                ! kv.fst.equalTo(k)
  98                ) {
  99            incr(ix);
 100            kv = elems[ix];
 101        }
 102
 103        return
 104            kv == null ? null : kv.snd;
 105    }
 106
 107    public KV findMin() {
 108        return
 109            undefined("findMin not implemented");
 110    }
 111
 112    public KV findMax() {
 113        return
 114            undefined("findMax not implemented");
 115    }
 116
 117    public SimpleHashMap insert(K kV v) {
 118        return
 119            insert(mkPair(k,v));
 120    }
 121
 122    public SimpleHashMap insert(KV p) {
 123        K   k  = p.fst;
 124        int ix = keyToHash(k);
 125        KV  kv = elems[ix];
 126
 127        while ( kv != null
 128                &&
 129                ! kv.fst.equalTo(k)
 130                ) {
 131            incr(ix);
 132            kv = elems[ix];
 133        }
 134
 135        if (kv == null) {
 136            // new elem
 137            elems[ix] = p;
 138            ++card;
 139        } else {
 140            // update of value
 141            elems[ix] = p;
 142        }
 143
 144        return
 145            checkExpand();
 146    }
 147
 148    public SimpleHashMap remove(K k) {
 149        return
 150            undefined("remove not implemented");
 151    }
 152
 153    public SimpleHashMap union(Map m2) {
 154        return
 155            unionWith(const2m2);
 156    }
 157
 158    public
 159    SimpleHashMap unionWith(Function2<V,V,V> op,
 160                                Map m2) {
 161        return undefined("unionWith not implemented");
 162    }
 163
 164    public
 165    SimpleHashMap difference(Map m2) {
 166        return
 167            differenceWith(null2m2);
 168    }
 169
 170    public
 171    SimpleHashMap differenceWith(Function2<V,V,V> op,
 172                                 Map m2) {
 173        return
 174            undefined("differenceWith not implemented");
 175    }
 176
 177    public SimpleHashMap copy() {
 178        return
 179            this;
 180    }
 181
 182    public Iterator<KV> iterator() {
 183        ++cntIter;
 184        return
 185            new HashMapIterator(this);
 186    }
 187
 188    public boolean inv() {
 189        for (int i = 0; i < elems.length++i) {
 190            if (elems[i] != null) {
 191                int ix = keyToHash(elems[i].fst);
 192
 193                /* all entries in hashtable
 194                   in the intervall [ix..i]
 195                   must be filled, otherwise the hash does not
 196                   fit to the position
 197                */
 198                int j = i;
 199                while (j != ix) {
 200                    decr(j);
 201                    if (elems[j] == null)
 202                        // unused cell found
 203                        return
 204                            false;
 205                }
 206            }
 207        }
 208
 209        return true;
 210    }
 211
 212    //----------------------------------------
 213    // internal methods
 214
 215    private static Function2<V,V,V> const2
 216        = new Function2<V,V,V>() {
 217        public V apply(V xV y) {
 218            return y;
 219        }
 220    };
 221
 222    private static Function2<V,V,V> null2
 223        = new Function2<V,V,V>() {
 224        public V apply(V xV y) {
 225            return null;
 226        }
 227    };
 228
 229    private int keyToHash(K k) {
 230        return
 231            k.hash() & (elems.length - 1);
 232    }
 233
 234    private int incr(int i) {
 235        ++i;
 236        return
 237            i == elems.length ? 0 : i;
 238    }
 239
 240    private int decr(int i) {
 241        return
 242            (i == 0 ? elems.length : i) - 1;
 243    }
 244
 245    private SimpleHashMap checkExpand() {
 246        if (card > elems.length) {
 247            return
 248                reorganize(* elems.length);
 249        }
 250        return this;
 251    }
 252
 253    private SimpleHashMap reorganize(int newSize) {
 254        SimpleHashMap nm = empty(newSize);
 255        for (int i = 0; i < elems.length++i) {
 256            nm = nm.insert(elems[i]);
 257        }
 258        return
 259            nm;
 260    }
 261
 262    private static
 263        class HashMapIterator
 264        extends ds.util.Iterator<KV> {
 265
 266        SimpleHashMap map;
 267        int len;
 268        int ix;
 269
 270        HashMapIterator(SimpleHashMap m) {
 271            map = m;
 272            ix  = 0;
 273            len = m.elems.length;
 274            advance();
 275            ++cntIter;
 276        }
 277
 278        public boolean hasNext() {
 279            return
 280                ix < len;
 281        }
 282
 283        private void advance() {
 284            while ( ix < len
 285                    &&
 286                    map.elems[ix] == null
 287                  ) {
 288                ++ix;
 289            }
 290        }
 291
 292        public KV next() {
 293            if ( ix == len )
 294                return
 295                    undefined("empty hashmap");
 296            KV res = map.elems[ix];
 297            ++ix;
 298            advance();
 299            return
 300                res;
 301        }
 302    }
 303
 304    //----------------------------------------
 305    // profiling
 306
 307    private static int cntMap  = 0;
 308    private static int spcMap = 0;
 309    private static int cntIter = 0;
 310
 311    public static String stats() {
 312        return
 313            "stats for ds.destructive.map.SimpleHashMap:\n" +
 314            "# new SimpleHashMap()      : " + cntMap + "\n" +
 315            "# words SimpleHashMap()    : " + spcMap + "\n" +
 316            "# new Iterator()           : " + cntIter + "\n";
 317    }
 318
 319    public String objStats() {
 320        int o =
 321            1 +   // SimpleHashMap
 322            1 +   // array
 323            card// KV
 324
 325        int f =
 326            2 +                // SimpleHashMap
 327            elems.length + 1 + // array
 328            card * 2;          // KV
 329        int m = o + f;
 330
 331        return
 332            "mem stats for ds.destructive.map.SimpleHashMap object:\n" +
 333            "# objects              : " + o + "\n" +
 334            "# fields               : " + f + "\n" +
 335            "# mem words            : " + m + "\n";
 336    }
 337}
weiter
Quellen
weiter

Letzte Änderung: 11.01.2017
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel