made work: multi-dimensional lists
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user