From a52cdc0c7f18ed6fa017037a458f80b98ebdcb16 Mon Sep 17 00:00:00 2001 From: Odweta Date: Mon, 25 Dec 2023 01:05:42 +0100 Subject: [PATCH] made work: multi-dimensional lists --- README.md | 13 +++++---- demo.c | 33 +++++++-------------- include/list.h | 4 +-- include/util.h | 10 +++++++ include/vector.h | 9 +----- src/list.c | 76 ++++++++++++++++++++++++++++++++++++++++-------- src/vector.c | 49 ++++++++++++++++++++++++++----- 7 files changed, 135 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 0b0b625..9bb02c0 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,8 @@ Examples of this work of art are in the `/examples/` directory of this repo. #### TODO: -1. Removing an element at a given index -2. Vectors of lists -3. Remove a value at a given index +1. Vectors of lists +2. Remove a value at a given index + You tell me @@ -56,12 +55,14 @@ Examples of this work of art are in the `/examples/` directory of this repo. 5. Cleanup of a list 6. Vectors inside of a list 7. Inserting at a given index +8. Lists of lists #### TODO: -1. Verify multi-dimensional lists working - lists of lists -2. Get/set at a given index -3. Remove at a given index +1. Get/set at a given index +2. Remove at a given index + ++ You tell me ## Installation diff --git a/demo.c b/demo.c index 4ee877e..2a31e52 100644 --- a/demo.c +++ b/demo.c @@ -3,34 +3,21 @@ #include int main() { - printf("creating a list using 'listInit()' (returns a list_t*)\n"); - list_t* l = listInit(); + list_t* another_list = listInit(); - printf("pushing an integer value into the list\nnote the kind of unusual way of passing the number argument: if you want to pass an expression (e.g. the value '1' or '4*4'), something not stored in a variable, you follow this syntax - &(type){value} (e.g. &(int){1 + 1})\nalso, the type of the variable must be given as the second argument to the function\n->'listPush(list_t*, INT, &(int){123})'\n"); - listPush(l, INT, &(int){123}); - listPrint(l); + listPush(another_list, CHAR, &(char){'x'}); + listPush(another_list, INT, &(int){123}); + listPush(another_list, FLOAT, &(float){3.14}); + listPush(another_list, LIST, another_list); - printf("popping the last value of the list; in this case, it is an integer, so you type: 'int poppedValue = *((int *)listPop(list_t*))'\n"); - int poppedValue = *((int *)listPop(l)); - printf("popped: %d\n", poppedValue); - listPrint(l); + vector_t* v = vectorInit(LIST); - printf("more examples with diferrent types\nnote that the vector_t* is a pointer, so there is no need to write the special syntax!\n"); - listPush(l, FLOAT, &(float){3.14}); - listPush(l, CHAR, &(char){'x'}); - vector_t* int_vec = vectorInit(INT); - vectorPush(int_vec, &(int){456}); - listPush(l, VECTOR, int_vec); + vectorPush(v, another_list); + vectorPush(v, another_list); - listPrint(l); + vectorPrint(v); - printf("inserting at index 1\n"); - listInsertAt(l, 1, FLOAT, &(float){6.67}); - - listPrint(l); - - printf("if you are finished working with the list BEFORE the immediate end of the program, run 'listCleanup(list_t*)', otherwise it is not strictly necessary\n"); - listCleanup(l); + vectorCleanup(v); return 0; } diff --git a/include/list.h b/include/list.h index d6d9a5f..a02ef68 100644 --- a/include/list.h +++ b/include/list.h @@ -8,8 +8,7 @@ */ #include - -typedef long unsigned int size_t; +#include typedef struct { size_t size; // number of elements that are inside the list @@ -22,6 +21,7 @@ list_t* listInit(); // r void listPush(list_t* l, dataType_e type, void* element); // appends an element at the end of a list void listPrint(list_t* l); // prints a list +void _listPrintRecursive(list_t* l, int depth); void listCleanup(list_t* l); // freeing pointers diff --git a/include/util.h b/include/util.h index 66c2265..028c173 100644 --- a/include/util.h +++ b/include/util.h @@ -1,6 +1,16 @@ #ifndef UTIL_H #define UTIL_H +typedef long unsigned int size_t; + +typedef enum { + INT = 0, + FLOAT = 1, + CHAR = 2, + VECTOR = 3, // allows for multi-dimensional arrays + LIST = 4 +} dataType_e; + char* intToString(int x); // convert an int into a string long pow(int x, int n); // x^n diff --git a/include/vector.h b/include/vector.h index 5272652..7ccb1b5 100644 --- a/include/vector.h +++ b/include/vector.h @@ -1,14 +1,7 @@ #ifndef VECTOR_H #define VECTOR_H -typedef long unsigned int size_t; - -typedef enum { - INT = 0, - FLOAT = 1, - CHAR = 2, - VECTOR = 3 // allows for multi-dimensional arrays -} dataType_e; +#include typedef struct { dataType_e type; diff --git a/src/list.c b/src/list.c index 534968b..46b106c 100644 --- a/src/list.c +++ b/src/list.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -48,6 +49,11 @@ listPush(list_t* l, dataType_e type, void* element) { vectorPush(newVec, element); vectorPush((vector_t *)l->data, newVec); break; + case LIST: + newVec = vectorInit(LIST); + vectorPush(newVec, element); + vectorPush((vector_t *)l->data, newVec); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); @@ -59,6 +65,41 @@ listPush(list_t* l, dataType_e type, void* element) { } } +void +_listPrintRecursive(list_t* l, int depth) { + fprintf(stdout, "["); + int i; + for (i = 0; i < l->size; i++) { + vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i); + + switch (ithVec->type) { + case INT: + printf("%d", *((int *)vectorGetAt(ithVec, 0))); + break; + case FLOAT: + printf("%f", *((float *)vectorGetAt(ithVec, 0))); + break; + case CHAR: + printf("'%c'", *((char *)vectorGetAt(ithVec, 0))); + break; + case VECTOR: + _printVectorRecursive(ithVec->data, 0); + break; + case LIST: + _listPrintRecursive(ithVec->data, 0); + break; + } + + if (i < l->size - 1) { + fprintf(stdout, ", "); + } + } + fprintf(stdout, "]"); + if (depth != 0) { + fprintf(stdout, "\n"); + } +} + void listPrint(list_t* l) { fprintf(stdout, "["); @@ -67,18 +108,21 @@ listPrint(list_t* l) { vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i); switch (ithVec->type) { - case INT: - printf("%d", *((int *)vectorGetAt(ithVec, 0))); - break; - case FLOAT: - printf("%f", *((float *)vectorGetAt(ithVec, 0))); - break; - case CHAR: - printf("'%c'", *((char *)vectorGetAt(ithVec, 0))); - break; - case VECTOR: - _printVectorRecursive(ithVec->data, 0); - break; + case INT: + printf("%d", *((int *)vectorGetAt(ithVec, 0))); + break; + case FLOAT: + printf("%f", *((float *)vectorGetAt(ithVec, 0))); + break; + case CHAR: + printf("'%c'", *((char *)vectorGetAt(ithVec, 0))); + break; + case VECTOR: + _printVectorRecursive(ithVec->data, 0); + break; + case LIST: + _listPrintRecursive(ithVec->data, 0); + break; } if (i < l->size - 1) { @@ -127,6 +171,9 @@ listInsertAt(list_t* l, int index, dataType_e type, void* element) { case VECTOR: listPush(l, VECTOR, element); break; + case LIST: + listPush(l, LIST, element); + break; } } else { vector_t* newVec; @@ -151,6 +198,11 @@ listInsertAt(list_t* l, int index, dataType_e type, void* element) { vectorPush(newVec, element); vectorInsertAt((vector_t *)l->data, index, newVec); break; + case LIST: + newVec = vectorInit(LIST); + vectorPush(newVec, element); + vectorInsertAt((vector_t *)l->data, index, newVec); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); diff --git a/src/vector.c b/src/vector.c index 05065ed..a63e021 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -73,6 +75,10 @@ vectorPrint(vector_t* v) { // Print an nD vector _printVectorRecursive((vector_t *)(v->data + i * v->elementSize), 0); break; + case LIST: + // Print an nD vector + _listPrintRecursive((list_t *)(v->data + i * v->elementSize), 0); + break; default: fprintf(stderr, "tried to print unsupported data type\n"); exit(EXIT_FAILURE); @@ -152,13 +158,16 @@ vectorInit(dataType_e type) { case VECTOR: v->elementSize = sizeof(vector_t); break; + case LIST: + v->elementSize = sizeof(list_t); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); } - v->data = malloc(v->elementSize * v->capacity); - if (v->data == NULL) { + v->data = malloc(v->elementSize * v->capacity); + if (!v->data) { fprintf(stderr, "failed to allocate memory for vector data\n"); exit(EXIT_FAILURE); } @@ -201,6 +210,15 @@ vectorPush(vector_t* v, void* element) { // Copy the vector data from the element to the vector memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t)); break; + case LIST: + v->data = realloc(v->data, v->elementSize * (v->size + 1)); + if (!v->data) { + fprintf(stderr, "failed to allocate memory for vector data\n"); + exit(EXIT_FAILURE); + } + + memcpy((vector_t*)(v->data) + v->size, (list_t*)element, sizeof(list_t)); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); @@ -241,12 +259,16 @@ vectorPop(vector_t* v) { v->size -= 1; if (v->size <= v->capacity / 2) v->capacity /= 2; if (v->capacity == 0) v->capacity = 1; - return vretval; + case LIST: + list_t* lretval = (list_t*)(v->data) + v->size-1; + v->size -= 1; + if (v->size <= v->capacity / 2) v->capacity /= 2; + if (v->capacity == 0) v->capacity = 1; + return lretval; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); - } } else { // cannot pop when there is no value in the vector @@ -309,13 +331,15 @@ void* vectorGetAt(vector_t* v, int index) { switch (v->type) { case INT: - return (int *)(v->data) + index; + return (int*)(v->data) + index; case FLOAT: - return (float *)(v->data) + index; + return (float*)(v->data) + index; case CHAR: - return (char *)(v->data) + index; + return (char*)(v->data) + index; case VECTOR: - return (vector_t *)(v->data) + index; + return (vector_t*)(v->data) + index; + case LIST: + return (list_t*)(v->data) + index; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); @@ -344,6 +368,9 @@ vectorSetAt(vector_t* v, int index, void* element) { case VECTOR: *((vector_t *)(v->data) + index) = *((vector_t *)element); break; + case LIST: + *((list_t *)(v->data) + index) = *((list_t *)element); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE); @@ -392,6 +419,12 @@ vectorInsertAt(vector_t* v, int index, void* element) { } *((vector_t *)(v->data) + index) = *((vector_t *)element); break; + case LIST: + for (int i = v->size-1; i > index; i--) { + *((list_t*)(v->data) + i) = *((list_t*)(v->data) + i-1); + } + *((list_t*)(v->data) + index) = *((list_t*)element); + break; default: fprintf(stderr, "specify a valid vector type\n"); exit(EXIT_FAILURE);