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