From 6d0c863a428bf8f4ad4ca566f3d8a731f6f860b6 Mon Sep 17 00:00:00 2001
From: Peter Gerwinski <peter.gerwinski@hs-bochum.de>
Date: Thu, 5 May 2022 15:12:06 +0200
Subject: [PATCH] =?UTF-8?q?Aktualisiertes=20Testprogramm=20f=C3=BCr=20Hash?=
 =?UTF-8?q?-Tabellen,=205.5.2022?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 20220505/hash-map-test-02.c |  97 +++++++++++++++++++++++++++++++++
 20220505/hash-map-test-03.c | 106 ++++++++++++++++++++++++++++++++++++
 2 files changed, 203 insertions(+)
 create mode 100644 20220505/hash-map-test-02.c
 create mode 100644 20220505/hash-map-test-03.c

diff --git a/20220505/hash-map-test-02.c b/20220505/hash-map-test-02.c
new file mode 100644
index 0000000..7a69934
--- /dev/null
+++ b/20220505/hash-map-test-02.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+const int ERROR = -1;
+const int size = 1117;
+const int bufsize = 100;
+
+int n[size];  // zunächst: alle 0
+const char *check[size];  // zunächst: alle NULL
+
+constexpr int hash (const char *name)
+{
+  // Cantor pairing function
+  uint8_t n0 = name ? name[0] : 0;
+  uint8_t n1 = n0 ? name[1] : 0;
+  uint8_t n2 = n1 ? name[2] : 0;
+  return ((n0 + n1) / 2 * (n0 + n1 + 1) + n2) % size;
+}
+
+void put_number (const char *name, int value)
+{
+  int idx = hash (name);
+  if (check[idx] && strcmp (check[idx], name) != 0)
+    fprintf (stderr, "occupied: %s = %d\n", name, value);
+  else
+    {
+      check[idx] = name;
+      n[idx] = value;
+    }
+}
+
+int get_number (const char *name)
+{
+  int value = ERROR;
+  int idx = hash (name);
+  if (check[idx] && strcmp (check[idx], name) == 0)
+    value = n[idx];
+  else
+    fprintf (stderr, "not found: %s\n", name);
+  return value;
+}
+
+static void read_data (FILE *f, char **name, int *value)
+{
+  int v;
+  char buffer[bufsize];
+  int bytes_read_1 = fscanf (f, "%d", &v);
+  char *bytes_read_2 = fgets (buffer, bufsize - 1, f);
+  int l = strlen (buffer);
+  if (l > 0 && buffer[l - 1] == '\n')
+    buffer[l - 1] = 0;
+  const char *n = buffer;
+  while (n[0] == ' ')
+    n++;
+  l = strlen (n);
+  if (l < 30)
+    printf ("l = %d, buffer = \"%s\", bytes_read_1 = %d, bytes_read_2 = %zx, errno = %d\n",
+            l, buffer, bytes_read_1, (size_t) bytes_read_2, errno);
+  if (*name == NULL)
+    *name = (char *) malloc (l);
+  strncpy (*name, n, l + 1);
+  *value = v;
+}
+
+int main (int argc, char **argv)
+{
+  const char *filename = "hash-test.dat";
+  if (argc > 1)
+    filename = argv[1];
+  FILE *f = fopen (filename, "r");
+  if (!f)
+    error (errno, errno, "cannot open file \"%s\"", filename);
+  while (!feof (f))
+    {
+      int value;
+      char *name = NULL;
+      read_data (f, &name, &value);
+      put_number (name, value);
+    }
+  rewind (f);
+  while (!feof (f))
+    {
+      int value;
+      char name[bufsize];
+      char *p = name;
+      read_data (f, &p, &value);
+      int v = get_number (name);
+      if (v != value)
+        printf ("%s: %d instead of %d\n", name, v, value);
+    }
+  fclose (f);
+  return 0;
+}
diff --git a/20220505/hash-map-test-03.c b/20220505/hash-map-test-03.c
new file mode 100644
index 0000000..06200c5
--- /dev/null
+++ b/20220505/hash-map-test-03.c
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+const int ERROR = -1;
+const int size = 1117;
+const int bufsize = 100;
+
+int n[size];  // zunächst: alle 0
+const char *check[size];  // zunächst: alle NULL
+
+constexpr int hash (const char *name)
+{
+  // Cantor pairing function
+  uint8_t n0 = name ? name[0] : 0;
+  uint8_t n1 = n0 ? name[1] : 0;
+  uint8_t n2 = n1 ? name[2] : 0;
+  return ((n0 + n1) / 2 * (n0 + n1 + 1) + n2) % size;
+}
+
+void put_number (const char *name, int value)
+{
+  int idx = hash (name);
+  if (check[idx] && strcmp (check[idx], name) != 0)
+    fprintf (stderr, "occupied: %s = %d\n", name, value);
+  else
+    {
+      check[idx] = name;
+      n[idx] = value;
+    }
+}
+
+int get_number (const char *name)
+{
+  int value = ERROR;
+  int idx = hash (name);
+  if (check[idx] && strcmp (check[idx], name) == 0)
+    value = n[idx];
+  else
+    fprintf (stderr, "not found: %s\n", name);
+  return value;
+}
+
+static void read_data (FILE *f, char **name, int *value)
+{
+  int v;
+  char buffer[bufsize];
+  int bytes_read_1 = fscanf (f, "%d", &v);
+  char *bytes_read_2 = fgets (buffer, bufsize - 1, f);
+  if (bytes_read_1 <= 0 || bytes_read_2 == NULL)
+    {
+      *name = NULL;
+      *value = -1;
+    }
+  else
+    {
+      int l = strlen (buffer);
+      if (l > 0 && buffer[l - 1] == '\n')
+        buffer[l - 1] = 0;
+      const char *n = buffer;
+      while (n[0] == ' ')
+        n++;
+      l = strlen (n);
+      if (*name == NULL)
+        *name = (char *) malloc (l);
+      strncpy (*name, n, l + 1);
+      *value = v;
+    }
+}
+
+int main (int argc, char **argv)
+{
+  const char *filename = "hash-test.dat";
+  if (argc > 1)
+    filename = argv[1];
+  FILE *f = fopen (filename, "r");
+  if (!f)
+    error (errno, errno, "cannot open file \"%s\"", filename);
+  while (!feof (f))
+    {
+      int value;
+      char *name = NULL;
+      read_data (f, &name, &value);
+      if (value >= 0 && name)
+        put_number (name, value);
+    }
+  rewind (f);
+  while (!feof (f))
+    {
+      int value;
+      char name[bufsize];
+      char *p = name;
+      read_data (f, &p, &value);
+      if (value >= 0 && name)
+        {
+          int v = get_number (name);
+          if (v != value)
+            printf ("%s: %d instead of %d\n", name, v, value);
+        }
+    }
+  fclose (f);
+  return 0;
+}
-- 
GitLab