From e6bb483dc264b628d11ab5a8ca20058273f0f151 Mon Sep 17 00:00:00 2001 From: Kevin Jerebica Date: Sun, 25 Aug 2024 22:24:08 +0200 Subject: [PATCH] feat: use char hashmap for child search --- README | 8 +++--- streecmp.c | 77 +++++++++++++++++++++++++++--------------------------- streecmp.h | 11 ++++---- test.c | 6 ++--- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/README b/README index 79a0d09..f013119 100644 --- a/README +++ b/README @@ -30,10 +30,12 @@ TECHNICALS TODO - * Characters "hashmap" to remove linear checking of children nodes - * Remove memory leaks - * Add alloc/free functions + * Detect strings which are already inside the tree + * Memory leaks + * Alloc/free functions * NULL checking + * Memset for initialization + * gentree with custom seperator COMMITS diff --git a/streecmp.c b/streecmp.c index 7ff170b..3486b60 100644 --- a/streecmp.c +++ b/streecmp.c @@ -1,43 +1,48 @@ #include #include #include +#include #include "streecmp.h" int strs_cnt = 0; -struct nod *mknod(struct nod *prnt) { - if (prnt == NULL) { +struct nod *allocnod(void) { + struct nod *nod = (struct nod *) calloc(1, sizeof(struct nod)); + if (nod == NULL) { return NULL; } - prnt->pool_size++; - - prnt->pool = (struct nod *) realloc(prnt->pool, - sizeof(struct nod)*prnt->pool_size); - if (prnt->pool == NULL) { + nod->pool = (struct nod **) calloc(256, sizeof(struct nod *)); + if (nod->pool == NULL) { + free(nod); return NULL; } - struct nod *child = &prnt->pool[prnt->pool_size-1]; - child->pool_size = 0; - child->pool = NULL; - child->val.cval = 0; - child->val.ival = 0; - - return child; + return nod; } -int mkstr(struct nod *rot, char *str) { - for (int i = 0; i < rot->pool_size; i++) { - struct nod *child = &rot->pool[i]; - if (child->val.cval != *str) { - continue; - } - - return mkstr(child, str+1); +struct nod *mknod(struct nod *nod, int loc) { + if (nod == NULL) { + return allocnod(); } - struct nod *new = mknod(rot); + if (nod->pool == NULL) { + return NULL; + } + + nod->pool_size++; + nod->pool[loc] = allocnod(); + + return nod->pool[loc]; +} + +int mkstr(struct nod *nod, char *str) { + struct nod *target = nod->pool[*str]; + if (target != NULL) { + return mkstr(target, str+1); + } + + struct nod *new = mknod(nod, *str); if (new == NULL) { return -1; } @@ -52,7 +57,7 @@ int mkstr(struct nod *rot, char *str) { return strs_cnt; } -int gentree(struct nod *rot, char *strs) { +int gentree(struct nod *nod, char *strs) { char *strs_cpy = strdup(strs); if (strs_cpy == NULL) { return -1; @@ -60,7 +65,7 @@ int gentree(struct nod *rot, char *strs) { for (char *tok = strtok(strs_cpy, "\n"); tok != NULL; tok = strtok(NULL, "\n")) { - int ret = mkstr(rot,tok); + int ret = mkstr(nod, tok); if (ret < 0) { return -1; } @@ -69,19 +74,15 @@ int gentree(struct nod *rot, char *strs) { return 0; } -int streecmp(struct nod *rot, char *str) { - for (int i = 0; i < rot->pool_size; i++) { - struct nod *child = &rot->pool[i]; - if (child->val.cval != *str) { - continue; - } - - if (child->val.cval == '\0') { - return child->val.ival; - } - - return streecmp(child, str+1); +int streecmp(struct nod *nod, char *str) { + struct nod *target = nod->pool[*str]; + if (target == NULL) { + return 0; } - return 0; + if (target->val.cval == '\0') { + return target->val.ival; + } + + return streecmp(target, str+1); } diff --git a/streecmp.h b/streecmp.h index a1971ff..8793f84 100644 --- a/streecmp.h +++ b/streecmp.h @@ -9,12 +9,13 @@ struct nodval { struct nod { struct nodval val; int pool_size; - struct nod *pool; + struct nod **pool; }; -struct nod *mknod(struct nod *prnt); -int mkstr(struct nod *rot, char *str); -int gentree(struct nod *rot, char *strs); -int streecmp(struct nod *rot, char *str); +struct nod *allocnod(void); +struct nod *mknod(struct nod *nod, int loc); +int mkstr(struct nod *nod, char *str); +int gentree(struct nod *nod, char *strs); +int streecmp(struct nod *nod, char *str); #endif diff --git a/test.c b/test.c index f14498d..d121785 100644 --- a/test.c +++ b/test.c @@ -114,7 +114,7 @@ char *strs = "A-IM\n" int main(void) { int ret; - struct nod *rot = (struct nod *) calloc(1, sizeof(struct nod)); + struct nod *rot = allocnod(); if (rot == NULL) { fprintf(stderr, "[-] Failed: not enough dynamic memory\n"); return -1; @@ -140,10 +140,10 @@ int main(void) { int found = streecmp(rot, tok); if (found == cnt) { fprintf(stdout, "[+][%d\t] Success: could find" - "'%s' in tree\n", cnt, tok); + " '%s' in tree\n", cnt, tok); } else { fprintf(stderr, "[-][%d\t] Error: could not find" - "'%s' in tree\n", cnt, tok); + " '%s' in tree\n", cnt, tok); } }