From 09fe600453f82b19fea26a260d2bf8dc699808f3 Mon Sep 17 00:00:00 2001 From: ayple Date: Sun, 12 May 2024 14:42:28 +0100 Subject: [PATCH] latest trie code --- .gitignore | 4 ++ trie/main.c | 22 ++++++++ trie/makefile | 0 trie/run.sh | 1 + trie/trie.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++ trie/trie.h | 24 ++++++++ 6 files changed, 205 insertions(+) create mode 100644 trie/main.c create mode 100644 trie/makefile create mode 100644 trie/run.sh create mode 100644 trie/trie.c create mode 100644 trie/trie.h diff --git a/.gitignore b/.gitignore index 1052555..736baf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# ides +.vscode +*.kdev4 + # Prerequisites *.d diff --git a/trie/main.c b/trie/main.c new file mode 100644 index 0000000..ae575e6 --- /dev/null +++ b/trie/main.c @@ -0,0 +1,22 @@ +#include "trie.h" +#include +#include + +int main() { + + TRIE* root = cdsc_trie_init(); + cdsc_trie_insert(root, "apple"); + cdsc_trie_insert(root, "apples"); + cdsc_trie_insert(root, "tomato"); + cdsc_trie_insert(root, "orange"); + cdsc_trie_insert(root, "ada"); + + printf("%d\n", cdsc_trie_contains(root, "apple")); + printf("%d\n", cdsc_trie_contains(root, "apples")); + cdsc_trie_delete_word(root, "apples"); + printf("%d\n", cdsc_trie_contains(root, "apple")); + printf("%d\n", cdsc_trie_contains(root, "apples")); + + printf("Finished!\n"); + return 0; +} diff --git a/trie/makefile b/trie/makefile new file mode 100644 index 0000000..e69de29 diff --git a/trie/run.sh b/trie/run.sh new file mode 100644 index 0000000..061b3b8 --- /dev/null +++ b/trie/run.sh @@ -0,0 +1 @@ +gcc trie.c \ No newline at end of file diff --git a/trie/trie.c b/trie/trie.c new file mode 100644 index 0000000..6a64e78 --- /dev/null +++ b/trie/trie.c @@ -0,0 +1,154 @@ +#include "trie.h" +#include +#include +#include + +TRIE* cdsc_trie_init() { + TRIE* root = (TRIE*) malloc(sizeof(TRIE)); + if (root == NULL) { + printf("Failed to allocate memory!"); + return NULL; + } + + root->value = '\0'; + root->final_chr = 0; + + for (int i = 0; i < ALPHABET_SIZE; i++) { + root->nodes[i] = NULL; + } + + return root; +} + + + +// Avoided using recursion for the insert as it makes unecessary stack +// calls. +void cdsc_trie_insert(TRIE* root, char word[]) { + struct trie_node* current = root; + size_t word_size = strlen(word); + size_t j = 0; + size_t i = 0; + + for (i = 0; i < ALPHABET_SIZE; i++) { + if (j == word_size) { + current->final_chr = true; + break; + } + + if (current->nodes[i] == NULL) { + current->nodes[i] = (struct trie_node*) malloc(sizeof(struct trie_node)); + current->nodes[i]->value = word[j]; + current = current->nodes[i]; + // printf("Allocated '%c' to '%p'\n", word[j], current); + i = 0; + j++; + continue; + } + + if (current->nodes[i]->value == word[j]) { + current = current->nodes[i]; + i = 0; + j++; + } + + } +} + +// This needs a rethink, two issues i can think of is +// if the node is last chr but also has child nodes, +// can't just free it straight away. +// alot more logical programming needs to be done here +// for more cases. +void cdsc_trie_delete_word(TRIE* root, char word[]) { + struct trie_node* current = root; + size_t word_size = strlen(word); + size_t j = 0; + size_t i = 0; + + for (i = 0; i < ALPHABET_SIZE; i++) { + if (j == word_size) { + if (current->final_chr) { + current->final_chr = false; + } + + break; + } + + if (current->nodes[i] == NULL) { + break; + } + + if (current->nodes[i]->value == word[j]) { + current = current->nodes[i]; + i = 0; + j++; + } + + } +} + + +bool cdsc_trie_contains(TRIE* head, char word[]) { + struct trie_node* current = head; + size_t word_size = strlen(word); + size_t j = 0; + size_t i = 0; + + for (i = 0; i < ALPHABET_SIZE; i++) { + if (j == word_size) { + return current->final_chr; + } + + if (current->nodes[i] == NULL) { + return false; + } + + // printf("Scanning %c\n", current->nodes[i]->value); + + if (current->nodes[i]->value == word[j]) { + current = current->nodes[i]; + i = 0; + j++; + } + + } + + return false; +} + +// TODO: this function needs testing +// void cdsc_trie_free(TRIE* head) { +// struct trie_node* current = head; + +// for (int i = 0; i < ALPHABET_SIZE; i++) { +// if (current->nodes[i] != NULL) { +// cdsdc_trie_free(current->nodes[i]); +// } + +// free(current->nodes[i]); +// } +// } + + +// if (head->nodes[i]->key == word[0]) { +// struct trie_node* current = head->nodes[i]->next; + +// for (size_t j = 1; j < strlen(word); j++) { +// if (current->key == word[j]) { +// continue; +// } + +// current->next = malloc(sizeof(struct trie_node)); + +// } + +// while (current != NULL) { +// if (current->key ) +// current = current->next; +// } + +// current = (struct trie_node*) malloc(sizeof(struct trie_node)); + +// break; +// } diff --git a/trie/trie.h b/trie/trie.h new file mode 100644 index 0000000..60e01aa --- /dev/null +++ b/trie/trie.h @@ -0,0 +1,24 @@ +#ifndef HEADER_TRIE_H_ +#define HEADER_TRIE_H_ + +#include // size_t +#include + +#define ALPHABET_SIZE 26 + + +typedef struct trie_node { + struct trie_node* nodes[ALPHABET_SIZE]; + char value; + bool final_chr; +} TRIE; + + + +TRIE* cdsc_trie_init(); +void cdsc_trie_insert(TRIE* head, char word[]); +void cdsc_trie_delete_word(TRIE* head, char word[]); +bool cdsc_trie_contains(TRIE* head, char word[]); +void cdsc_trie_free(TRIE* head); + +#endif \ No newline at end of file