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:
|
#### TODO:
|
||||||
|
|
||||||
1. Removing an element at a given index
|
1. Vectors of lists
|
||||||
2. Vectors of lists
|
2. Remove a value at a given index
|
||||||
3. Remove a value at a given index
|
|
||||||
|
|
||||||
+ You tell me
|
+ 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
|
5. Cleanup of a list
|
||||||
6. Vectors inside of a list
|
6. Vectors inside of a list
|
||||||
7. Inserting at a given index
|
7. Inserting at a given index
|
||||||
|
8. Lists of lists
|
||||||
|
|
||||||
#### TODO:
|
#### TODO:
|
||||||
|
|
||||||
1. Verify multi-dimensional lists working - lists of lists
|
1. Get/set at a given index
|
||||||
2. Get/set at a given index
|
2. Remove at a given index
|
||||||
3. Remove at a given index
|
|
||||||
|
+ You tell me
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -3,34 +3,21 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("creating a list using 'listInit()' (returns a list_t*)\n");
|
list_t* another_list = listInit();
|
||||||
list_t* l = 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(another_list, CHAR, &(char){'x'});
|
||||||
listPush(l, INT, &(int){123});
|
listPush(another_list, INT, &(int){123});
|
||||||
listPrint(l);
|
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");
|
vector_t* v = vectorInit(LIST);
|
||||||
int poppedValue = *((int *)listPop(l));
|
|
||||||
printf("popped: %d\n", poppedValue);
|
|
||||||
listPrint(l);
|
|
||||||
|
|
||||||
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");
|
vectorPush(v, another_list);
|
||||||
listPush(l, FLOAT, &(float){3.14});
|
vectorPush(v, another_list);
|
||||||
listPush(l, CHAR, &(char){'x'});
|
|
||||||
vector_t* int_vec = vectorInit(INT);
|
|
||||||
vectorPush(int_vec, &(int){456});
|
|
||||||
listPush(l, VECTOR, int_vec);
|
|
||||||
|
|
||||||
listPrint(l);
|
vectorPrint(v);
|
||||||
|
|
||||||
printf("inserting at index 1\n");
|
vectorCleanup(v);
|
||||||
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);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <odweta/vector.h>
|
#include <odweta/vector.h>
|
||||||
|
#include <odweta/util.h>
|
||||||
typedef long unsigned int size_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t size; // number of elements that are inside the list
|
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 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 listPrint(list_t* l); // prints a list
|
||||||
|
void _listPrintRecursive(list_t* l, int depth);
|
||||||
|
|
||||||
void listCleanup(list_t* l); // freeing pointers
|
void listCleanup(list_t* l); // freeing pointers
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
#ifndef UTIL_H
|
#ifndef UTIL_H
|
||||||
#define 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
|
char* intToString(int x); // convert an int into a string
|
||||||
|
|
||||||
long pow(int x, int n); // x^n
|
long pow(int x, int n); // x^n
|
||||||
|
|||||||
+1
-8
@@ -1,14 +1,7 @@
|
|||||||
#ifndef VECTOR_H
|
#ifndef VECTOR_H
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
typedef long unsigned int size_t;
|
#include <odweta/util.h>
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
INT = 0,
|
|
||||||
FLOAT = 1,
|
|
||||||
CHAR = 2,
|
|
||||||
VECTOR = 3 // allows for multi-dimensional arrays
|
|
||||||
} dataType_e;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
dataType_e type;
|
dataType_e type;
|
||||||
|
|||||||
+64
-12
@@ -1,5 +1,6 @@
|
|||||||
#include <odweta/list.h>
|
#include <odweta/list.h>
|
||||||
#include <odweta/vector.h>
|
#include <odweta/vector.h>
|
||||||
|
#include <odweta/util.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -48,6 +49,11 @@ listPush(list_t* l, dataType_e type, void* element) {
|
|||||||
vectorPush(newVec, element);
|
vectorPush(newVec, element);
|
||||||
vectorPush((vector_t *)l->data, newVec);
|
vectorPush((vector_t *)l->data, newVec);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
newVec = vectorInit(LIST);
|
||||||
|
vectorPush(newVec, element);
|
||||||
|
vectorPush((vector_t *)l->data, newVec);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
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
|
void
|
||||||
listPrint(list_t* l) {
|
listPrint(list_t* l) {
|
||||||
fprintf(stdout, "[");
|
fprintf(stdout, "[");
|
||||||
@@ -67,18 +108,21 @@ listPrint(list_t* l) {
|
|||||||
vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i);
|
vector_t *ithVec = (vector_t *)vectorGetAt((vector_t *)l->data, i);
|
||||||
|
|
||||||
switch (ithVec->type) {
|
switch (ithVec->type) {
|
||||||
case INT:
|
case INT:
|
||||||
printf("%d", *((int *)vectorGetAt(ithVec, 0)));
|
printf("%d", *((int *)vectorGetAt(ithVec, 0)));
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
printf("%f", *((float *)vectorGetAt(ithVec, 0)));
|
printf("%f", *((float *)vectorGetAt(ithVec, 0)));
|
||||||
break;
|
break;
|
||||||
case CHAR:
|
case CHAR:
|
||||||
printf("'%c'", *((char *)vectorGetAt(ithVec, 0)));
|
printf("'%c'", *((char *)vectorGetAt(ithVec, 0)));
|
||||||
break;
|
break;
|
||||||
case VECTOR:
|
case VECTOR:
|
||||||
_printVectorRecursive(ithVec->data, 0);
|
_printVectorRecursive(ithVec->data, 0);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
_listPrintRecursive(ithVec->data, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < l->size - 1) {
|
if (i < l->size - 1) {
|
||||||
@@ -127,6 +171,9 @@ listInsertAt(list_t* l, int index, dataType_e type, void* element) {
|
|||||||
case VECTOR:
|
case VECTOR:
|
||||||
listPush(l, VECTOR, element);
|
listPush(l, VECTOR, element);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
listPush(l, LIST, element);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vector_t* newVec;
|
vector_t* newVec;
|
||||||
@@ -151,6 +198,11 @@ listInsertAt(list_t* l, int index, dataType_e type, void* element) {
|
|||||||
vectorPush(newVec, element);
|
vectorPush(newVec, element);
|
||||||
vectorInsertAt((vector_t *)l->data, index, newVec);
|
vectorInsertAt((vector_t *)l->data, index, newVec);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
newVec = vectorInit(LIST);
|
||||||
|
vectorPush(newVec, element);
|
||||||
|
vectorInsertAt((vector_t *)l->data, index, newVec);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
+41
-8
@@ -1,4 +1,6 @@
|
|||||||
#include <odweta/vector.h>
|
#include <odweta/vector.h>
|
||||||
|
#include <odweta/util.h>
|
||||||
|
#include <odweta/list.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -73,6 +75,10 @@ vectorPrint(vector_t* v) {
|
|||||||
// Print an nD vector
|
// Print an nD vector
|
||||||
_printVectorRecursive((vector_t *)(v->data + i * v->elementSize), 0);
|
_printVectorRecursive((vector_t *)(v->data + i * v->elementSize), 0);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
// Print an nD vector
|
||||||
|
_listPrintRecursive((list_t *)(v->data + i * v->elementSize), 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "tried to print unsupported data type\n");
|
fprintf(stderr, "tried to print unsupported data type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -152,13 +158,16 @@ vectorInit(dataType_e type) {
|
|||||||
case VECTOR:
|
case VECTOR:
|
||||||
v->elementSize = sizeof(vector_t);
|
v->elementSize = sizeof(vector_t);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
v->elementSize = sizeof(list_t);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
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");
|
fprintf(stderr, "failed to allocate memory for vector data\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -201,6 +210,15 @@ vectorPush(vector_t* v, void* element) {
|
|||||||
// Copy the vector data from the element to the vector
|
// Copy the vector data from the element to the vector
|
||||||
memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t));
|
memcpy((vector_t *)(v->data) + v->size, (vector_t *)element, sizeof(vector_t));
|
||||||
break;
|
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:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -241,12 +259,16 @@ vectorPop(vector_t* v) {
|
|||||||
v->size -= 1;
|
v->size -= 1;
|
||||||
if (v->size <= v->capacity / 2) v->capacity /= 2;
|
if (v->size <= v->capacity / 2) v->capacity /= 2;
|
||||||
if (v->capacity == 0) v->capacity = 1;
|
if (v->capacity == 0) v->capacity = 1;
|
||||||
|
|
||||||
return vretval;
|
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:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// cannot pop when there is no value in the vector
|
// cannot pop when there is no value in the vector
|
||||||
@@ -309,13 +331,15 @@ void*
|
|||||||
vectorGetAt(vector_t* v, int index) {
|
vectorGetAt(vector_t* v, int index) {
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case INT:
|
case INT:
|
||||||
return (int *)(v->data) + index;
|
return (int*)(v->data) + index;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
return (float *)(v->data) + index;
|
return (float*)(v->data) + index;
|
||||||
case CHAR:
|
case CHAR:
|
||||||
return (char *)(v->data) + index;
|
return (char*)(v->data) + index;
|
||||||
case VECTOR:
|
case VECTOR:
|
||||||
return (vector_t *)(v->data) + index;
|
return (vector_t*)(v->data) + index;
|
||||||
|
case LIST:
|
||||||
|
return (list_t*)(v->data) + index;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -344,6 +368,9 @@ vectorSetAt(vector_t* v, int index, void* element) {
|
|||||||
case VECTOR:
|
case VECTOR:
|
||||||
*((vector_t *)(v->data) + index) = *((vector_t *)element);
|
*((vector_t *)(v->data) + index) = *((vector_t *)element);
|
||||||
break;
|
break;
|
||||||
|
case LIST:
|
||||||
|
*((list_t *)(v->data) + index) = *((list_t *)element);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -392,6 +419,12 @@ vectorInsertAt(vector_t* v, int index, void* element) {
|
|||||||
}
|
}
|
||||||
*((vector_t *)(v->data) + index) = *((vector_t *)element);
|
*((vector_t *)(v->data) + index) = *((vector_t *)element);
|
||||||
break;
|
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:
|
default:
|
||||||
fprintf(stderr, "specify a valid vector type\n");
|
fprintf(stderr, "specify a valid vector type\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
Reference in New Issue
Block a user