Update to use HashMap with chaining, cli args, and freeing all memory (no leaks).
This commit is contained in:
parent
2956811807
commit
a8bcc6899c
@ -3,3 +3,6 @@ twoSum: runTwoSum.c twoSum.c
|
|||||||
|
|
||||||
run: twoSum
|
run: twoSum
|
||||||
./twoSum
|
./twoSum
|
||||||
|
|
||||||
|
valgrind: twoSum
|
||||||
|
valgrind --leak-check=full ./twoSum -t 3 1 2
|
@ -1,26 +1,40 @@
|
|||||||
#include "./twoSum.c"
|
#include "./twoSum.c"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int main() {
|
#define USAGE "Usage: twoSum -t <target> <e0> <e1> [...<es>]\n"
|
||||||
int nums[] = { 0, 4, 3, 0 };
|
|
||||||
int returnSize = 0;
|
int main(int argc, char *argv[]) {
|
||||||
int *result = twoSum(nums, 4, 0, &returnSize);
|
if (argc < 5) {
|
||||||
bool foundFirst, foundSecond;
|
fprintf(stderr, USAGE);
|
||||||
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");
|
|
||||||
return 1;
|
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;
|
||||||
}
|
}
|
||||||
|
104
two-sum/twoSum.c
104
two-sum/twoSum.c
@ -4,15 +4,20 @@ typedef struct {
|
|||||||
int key, value;
|
int key, value;
|
||||||
} HashMapEntry;
|
} HashMapEntry;
|
||||||
|
|
||||||
|
typedef struct EntryList {
|
||||||
|
HashMapEntry *entry;
|
||||||
|
struct EntryList *next;
|
||||||
|
} EntryList;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int size;
|
int size;
|
||||||
HashMapEntry **entries;
|
EntryList **entries;
|
||||||
} HashMap;
|
} HashMap;
|
||||||
|
|
||||||
HashMap *makeHashMap(int size) {
|
HashMap *makeHashMap(int size) {
|
||||||
HashMap *m = malloc(sizeof(HashMap));
|
HashMap *m = malloc(sizeof(HashMap));
|
||||||
m->size = size;
|
m->size = size;
|
||||||
m->entries = malloc(size * sizeof(HashMapEntry*));
|
m->entries = malloc(size * sizeof(EntryList *));
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
m->entries[i] = NULL;
|
m->entries[i] = NULL;
|
||||||
}
|
}
|
||||||
@ -30,48 +35,72 @@ HashMapEntry *makeEntry(int key, int value) {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PUT_SUCCESS 1
|
EntryList *makeLinkedList(HashMapEntry *e) {
|
||||||
#define PUT_FAIL 0
|
EntryList *l = malloc(sizeof(EntryList));
|
||||||
|
l->entry = e;
|
||||||
int putAt(HashMap *m, HashMapEntry *e, int index) {
|
l->next = NULL;
|
||||||
if (m->entries[index] == NULL) {
|
return l;
|
||||||
m->entries[index] = e;
|
|
||||||
return PUT_SUCCESS;
|
|
||||||
}
|
|
||||||
return PUT_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
int hash = hashCode(m, key);
|
||||||
HashMapEntry *e = makeEntry(key, value);
|
HashMapEntry *e = makeEntry(key, value);
|
||||||
for (int i = hash; i < m->size; i++) {
|
putAt(m, e, hash);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMapEntry *get(HashMap *m, int key) {
|
HashMapEntry *get(HashMap *m, int key) {
|
||||||
int hash = hashCode(m, key);
|
int hash = hashCode(m, key);
|
||||||
for (int i = hash; i < m->size; i++) {
|
EntryList *l = m->entries[hash];
|
||||||
if (m->entries[i] != NULL) {
|
while (l != NULL && l->entry->key != key) {
|
||||||
HashMapEntry *e = m->entries[i];
|
l = l->next;
|
||||||
if (e->key == key) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < hash; i++) {
|
if (l == NULL) return NULL;
|
||||||
if (m->entries[i] != NULL) {
|
return l->entry;
|
||||||
HashMapEntry *e = m->entries[i];
|
}
|
||||||
if (e->key == key) {
|
|
||||||
return e;
|
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[0] = i;
|
||||||
result[1] = e->value;
|
result[1] = e->value;
|
||||||
*returnSize = 2;
|
*returnSize = 2;
|
||||||
|
freeHashMap(m);
|
||||||
return result;
|
return result;
|
||||||
} else if (!put(m, nums[i], i)) {
|
} else {
|
||||||
*returnSize = 0;
|
put(m, nums[i], i);
|
||||||
return malloc(0); // fail
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
freeHashMap(m);
|
||||||
*returnSize = 0;
|
*returnSize = 0;
|
||||||
return malloc(0);
|
return malloc(0);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user