made work: multi-dimensional lists

This commit is contained in:
Odweta
2023-12-25 01:05:42 +01:00
parent 7233f8c8af
commit a52cdc0c7f
7 changed files with 135 additions and 59 deletions
+7 -6
View File
@@ -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
+10 -23
View File
@@ -3,34 +3,21 @@
#include <stdio.h>
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;
}
+2 -2
View File
@@ -8,8 +8,7 @@
*/
#include <odweta/vector.h>
typedef long unsigned int size_t;
#include <odweta/util.h>
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
+10
View File
@@ -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
+1 -8
View File
@@ -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 <odweta/util.h>
typedef struct {
dataType_e type;
+64 -12
View File
@@ -1,5 +1,6 @@
#include <odweta/list.h>
#include <odweta/vector.h>
#include <odweta/util.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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);
+41 -8
View File
@@ -1,4 +1,6 @@
#include <odweta/vector.h>
#include <odweta/util.h>
#include <odweta/list.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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);