Pārlūkot izejas kodu

hashing for strings

Kajetan Johannes Hammerle 4 gadi atpakaļ
vecāks
revīzija
90a873ddab
2 mainītis faili ar 45 papildinājumiem un 1 dzēšanām
  1. 24 0
      tests/StringBufferTests.cpp
  2. 21 1
      utils/StringBuffer.h

+ 24 - 0
tests/StringBufferTests.cpp

@@ -1,6 +1,7 @@
 #include "tests/StringBufferTests.h"
 #include "tests/Test.h"
 #include "utils/StringBuffer.h"
+#include "utils/HashMap.h"
 
 typedef StringBuffer<20> String;
 
@@ -96,6 +97,27 @@ static void testAppendChar(Test& test) {
     test.checkEqual(4, s.getLength(), "length after char append with overflow");
 }
 
+static void testHashCode(Test& test) {
+    String s;
+    s.append("a").append("bc").append(20).append(25.5f).append(true);
+    test.checkEqual(String("abc2025.50true").hashCode(), s.hashCode(), "string modification recalculates hash 1");
+    s.clear();
+    test.checkEqual(String().hashCode(), s.hashCode(), "string modification recalculates hash 2");
+}
+
+static void testAsHashMapKey(Test& test) {
+    HashMap<String, int, 5> map;
+    
+    map.add(String("wusi"), 3);
+    map.add(String("hiThere"), 7);
+    map.add(String("baum123"), 5);
+    
+    test.checkEqual(3, map.search(String("wusi"), 0), "strings works as hash key 1");
+    test.checkEqual(7, map.search(String("hiThere"), 0), "strings works as hash key 2");
+    test.checkEqual(5, map.search(String("baum123"), 0), "strings works as hash key 3");
+    test.checkEqual(0, map.search(String("423hifd"), 0), "strings works as hash key 4");
+}
+
 void StringBufferTests::test() {
     Test test("StringBuffer");
     testEquality(test);
@@ -111,5 +133,7 @@ void StringBufferTests::test() {
     testBool(test);
     testClear(test);
     testAppendChar(test);
+    testHashCode(test);
+    testAsHashMapKey(test);
     test.finalize();
 }

+ 21 - 1
utils/StringBuffer.h

@@ -6,11 +6,22 @@
 template<int N>
 class StringBuffer final {
     int length;
+    int hash;
     char data[N];
 
+    void addToHash(char c) {
+        hash = 31 * hash + c;
+    }
+
+    void addToHash(int from, int to) {
+        for(int i = from; i < to; i++) {
+            addToHash(data[i]);
+        }
+    }
+
 public:
 
-    StringBuffer() : length(0) {
+    StringBuffer() : length(0), hash(0) {
         data[0] = '\0';
     }
 
@@ -49,6 +60,7 @@ public:
     StringBuffer& append(char c) {
         if(length < N - 1) {
             data[length++] = c;
+            addToHash(c);
             data[length] = '\0';
         }
         return *this;
@@ -57,6 +69,7 @@ public:
     StringBuffer& append(const char* str) {
         for(int i = 0; length < N - 1 && str[i] != '\0'; length++, i++) {
             data[length] = str[i];
+            addToHash(str[i]);
         }
         data[length] = '\0';
         return *this;
@@ -66,11 +79,13 @@ public:
     StringBuffer& append(const char* format, const T& t) {
         int left = N - length;
         int written = snprintf(data + length, left, format, t);
+        int oldLength = length;
         if(written < left) {
             length += written;
         } else {
             length = N - 1;
         }
+        addToHash(oldLength, length);
         return *this;
     }
 
@@ -88,9 +103,14 @@ public:
 
     StringBuffer& clear() {
         length = 0;
+        hash = 0;
         data[0] = '\0';
         return *this;
     }
+
+    int hashCode() const {
+        return hash;
+    }
 };
 
 template<int N>