From a8bcc6899ce7362808fd445667af9dd5039c4ea6 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Tue, 11 Feb 2025 17:19:23 -0600 Subject: [PATCH] Update to use HashMap with chaining, cli args, and freeing all memory (no leaks). --- two-sum/Makefile | 3 ++ two-sum/runTwoSum.c | 54 ++++++++++++++--------- two-sum/twoSum.c | 104 ++++++++++++++++++++++++++++---------------- 3 files changed, 104 insertions(+), 57 deletions(-) diff --git a/two-sum/Makefile b/two-sum/Makefile index cf8a1c5..cacf3b0 100644 --- a/two-sum/Makefile +++ b/two-sum/Makefile @@ -3,3 +3,6 @@ twoSum: runTwoSum.c twoSum.c run: twoSum ./twoSum + +valgrind: twoSum + valgrind --leak-check=full ./twoSum -t 3 1 2 \ No newline at end of file diff --git a/two-sum/runTwoSum.c b/two-sum/runTwoSum.c index 386bb1f..49a49cc 100644 --- a/two-sum/runTwoSum.c +++ b/two-sum/runTwoSum.c @@ -1,26 +1,40 @@ #include "./twoSum.c" -#include #include +#include -int main() { - int nums[] = { 0, 4, 3, 0 }; - int returnSize = 0; - int *result = twoSum(nums, 4, 0, &returnSize); - bool foundFirst, foundSecond; - for (int i = 0; i < returnSize; i++) { - switch (result[i]) { - case 0: - foundFirst = true; - break; - case 3: - foundSecond = true; - break; - } - } - if (foundFirst && foundSecond) { - return 0; - } else { - fprintf(stderr, "Did not find indices [0, 1]\n"); +#define USAGE "Usage: twoSum -t [...]\n" + +int main(int argc, char *argv[]) { + if (argc < 5) { + fprintf(stderr, USAGE); return 1; } + if (strcmp("-t", argv[1]) != 0) { + fprintf(stderr, USAGE); + return 1; + } + int target = atoi(argv[2]); + int *nums = malloc(sizeof(int) * (argc - 3)); + + for (int i = 3; i < argc; i++) { + nums[i - 3] = atoi(argv[i]); + } + + int returnSize = 0; + int *result = twoSum(nums, argc - 3, target, &returnSize); + + if (!returnSize) { + fprintf(stderr, "Did not find two indices."); + return 1; + } + + for (int i = 0; i < returnSize; i++) { + printf("%i ", result[i]); + } + printf("\n"); + + free(result); + free(nums); + + return 0; } diff --git a/two-sum/twoSum.c b/two-sum/twoSum.c index ce75c12..e6221b6 100644 --- a/two-sum/twoSum.c +++ b/two-sum/twoSum.c @@ -4,15 +4,20 @@ typedef struct { int key, value; } HashMapEntry; +typedef struct EntryList { + HashMapEntry *entry; + struct EntryList *next; +} EntryList; + typedef struct { int size; - HashMapEntry **entries; + EntryList **entries; } HashMap; HashMap *makeHashMap(int size) { HashMap *m = malloc(sizeof(HashMap)); m->size = size; - m->entries = malloc(size * sizeof(HashMapEntry*)); + m->entries = malloc(size * sizeof(EntryList *)); for (int i = 0; i < size; i++) { m->entries[i] = NULL; } @@ -30,48 +35,72 @@ HashMapEntry *makeEntry(int key, int value) { return e; } -#define PUT_SUCCESS 1 -#define PUT_FAIL 0 - -int putAt(HashMap *m, HashMapEntry *e, int index) { - if (m->entries[index] == NULL) { - m->entries[index] = e; - return PUT_SUCCESS; - } - return PUT_FAIL; +EntryList *makeLinkedList(HashMapEntry *e) { + EntryList *l = malloc(sizeof(EntryList)); + l->entry = e; + l->next = NULL; + return l; } -int put(HashMap *m, int key, int value) { +void appendEntryList(EntryList *l, HashMapEntry *e) { + while (l->next != NULL) + l = l->next; + l->next = makeLinkedList(e); +} + +void putAt(HashMap *m, HashMapEntry *e, int index) { + if (m->entries[index] == NULL) { + m->entries[index] = makeLinkedList(e); + } else { + appendEntryList(m->entries[index], e); + } +} + +void put(HashMap *m, int key, int value) { int hash = hashCode(m, key); HashMapEntry *e = makeEntry(key, value); - for (int i = hash; i < m->size; i++) { - if (putAt(m, e, i)) return PUT_SUCCESS; - } - for (int i = 0; i < hash; i++) { - if (putAt(m, e,i)) return PUT_SUCCESS; - } - return PUT_FAIL; + putAt(m, e, hash); } HashMapEntry *get(HashMap *m, int key) { int hash = hashCode(m, key); - for (int i = hash; i < m->size; i++) { - if (m->entries[i] != NULL) { - HashMapEntry *e = m->entries[i]; - if (e->key == key) { - return e; - } - } + EntryList *l = m->entries[hash]; + while (l != NULL && l->entry->key != key) { + l = l->next; } - for (int i = 0; i < hash; i++) { - if (m->entries[i] != NULL) { - HashMapEntry *e = m->entries[i]; - if (e->key == key) { - return e; - } - } + if (l == NULL) return NULL; + return l->entry; +} + +void freeEntryList(EntryList *l) { + int size = 0; + EntryList *current = l; + while (current != NULL) { + current = current->next; + size++; } - return NULL; + + EntryList **reversed = malloc(size * sizeof(EntryList *)); + current = l; + for (int i = 0; i < size; i++) { + reversed[size - i - 1] = current; + current = current->next; + } + + for (int i = 0; i < size; i++) { + free(reversed[i]->entry); + free(reversed[i]); + } + + free(reversed); +} + +void freeHashMap(HashMap *m) { + for (int i = 0; i < m->size; i++) { + freeEntryList(m->entries[i]); + } + free(m->entries); + free(m); } /** @@ -87,12 +116,13 @@ int* twoSum(int* nums, int numsSize, int target, int* returnSize) { result[0] = i; result[1] = e->value; *returnSize = 2; + freeHashMap(m); return result; - } else if (!put(m, nums[i], i)) { - *returnSize = 0; - return malloc(0); // fail + } else { + put(m, nums[i], i); } } + freeHashMap(m); *returnSize = 0; return malloc(0); } \ No newline at end of file