/** * File: vector.h * Created Time: 2023-07-13 * Author: Zuoxun (845242523@qq.com)、Gonglja (glj0@outlook.com) */ #ifndef VECTOR_H #define VECTOR_H #ifdef __cplusplus extern "C" { #endif /* Define vector type */ typedef struct vector { int size; // Current vector size int capacity; // Current vector capacity int depth; // Current vector depth void **data; // Pointer array to data } vector; /* Construct vector */ vector *newVector() { vector *v = malloc(sizeof(vector)); v->size = 0; v->capacity = 4; v->depth = 1; v->data = malloc(v->capacity * sizeof(void *)); return v; } /* Construct vector with specified size and default value */ vector *_newVector(int size, void *elem, int elemSize) { vector *v = malloc(sizeof(vector)); v->size = size; v->capacity = size; v->depth = 1; v->data = malloc(v->capacity * sizeof(void *)); for (int i = 0; i < size; i++) { void *tmp = malloc(sizeof(char) * elemSize); memcpy(tmp, elem, elemSize); v->data[i] = tmp; } return v; } /* Destruct vector */ void delVector(vector *v) { if (v) { if (v->depth == 0) { return; } else if (v->depth == 1) { for (int i = 0; i < v->size; i++) { free(v->data[i]); } free(v); } else { for (int i = 0; i < v->size; i++) { delVector(v->data[i]); } v->depth--; } } } /* Add element (by copy) to vector tail */ void vectorPushback(vector *v, void *elem, int elemSize) { if (v->size == v->capacity) { v->capacity *= 2; v->data = realloc(v->data, v->capacity * sizeof(void *)); } void *tmp = malloc(sizeof(char) * elemSize); memcpy(tmp, elem, elemSize); v->data[v->size++] = tmp; } /* Pop element from vector tail */ void vectorPopback(vector *v) { if (v->size != 0) { free(v->data[v->size - 1]); v->size--; } } /* Clear vector */ void vectorClear(vector *v) { delVector(v); v->size = 0; v->capacity = 4; v->depth = 1; v->data = malloc(v->capacity * sizeof(void *)); } /* Get vector size */ int vectorSize(vector *v) { return v->size; } /* Get vector tail element */ void *vectorBack(vector *v) { int n = v->size; return n > 0 ? v->data[n - 1] : NULL; } /* Get vector head element */ void *vectorFront(vector *v) { return v->size > 0 ? v->data[0] : NULL; } /* Get vector element at index pos */ void *vectorAt(vector *v, int pos) { if (pos < 0 || pos >= v->size) { printf("vectorAt: out of range\n"); return NULL; } return v->data[pos]; } /* Set vector element at index pos */ void vectorSet(vector *v, int pos, void *elem, int elemSize) { if (pos < 0 || pos >= v->size) { printf("vectorSet: out of range\n"); return; } free(v->data[pos]); void *tmp = malloc(sizeof(char) * elemSize); memcpy(tmp, elem, elemSize); v->data[pos] = tmp; } /* Expand vector capacity */ void vectorExpand(vector *v) { v->capacity *= 2; v->data = realloc(v->data, v->capacity * sizeof(void *)); } /* Shrink vector capacity */ void vectorShrink(vector *v) { v->capacity /= 2; v->data = realloc(v->data, v->capacity * sizeof(void *)); } /* Insert element at vector index pos */ void vectorInsert(vector *v, int pos, void *elem, int elemSize) { if (v->size == v->capacity) { vectorExpand(v); } for (int j = v->size; j > pos; j--) { v->data[j] = v->data[j - 1]; } void *tmp = malloc(sizeof(char) * elemSize); memcpy(tmp, elem, elemSize); v->data[pos] = tmp; v->size++; } /* Delete element at vector index pos */ void vectorErase(vector *v, int pos) { if (v->size != 0) { free(v->data[pos]); for (int j = pos; j < v->size - 1; j++) { v->data[j] = v->data[j + 1]; } v->size--; } } /* Swap vector elements */ void vectorSwap(vector *v, int i, int j) { void *tmp = v->data[i]; v->data[i] = v->data[j]; v->data[j] = tmp; } /* Is vector empty */ bool vectorEmpty(vector *v) { return v->size == 0; } /* Is vector full */ bool vectorFull(vector *v) { return v->size == v->capacity; } /* Are vectors equal */ bool vectorEqual(vector *v1, vector *v2) { if (v1->size != v2->size) { printf("size not equal\n"); return false; } for (int i = 0; i < v1->size; i++) { void *a = v1->data[i]; void *b = v2->data[i]; if (memcmp(a, b, sizeof(a)) != 0) { printf("data %d not equal\n", i); return false; } } return true; } /* Sort vector internally */ void vectorSort(vector *v, int (*cmp)(const void *, const void *)) { qsort(v->data, v->size, sizeof(void *), cmp); } /* Print function, need to pass a function to print variables */ /* Currently only supports printing vector with depth 1 */ void printVector(vector *v, void (*printFunc)(vector *v, void *p)) { if (v) { if (v->depth == 0) { return; } else if (v->depth == 1) { if(v->size == 0) { printf("\n"); return; } for (int i = 0; i < v->size; i++) { if (i == 0) { printf("["); } else if (i == v->size - 1) { printFunc(v, v->data[i]); printf("]\r\n"); break; } printFunc(v, v->data[i]); printf(","); } } else { for (int i = 0; i < v->size; i++) { printVector(v->data[i], printFunc); } v->depth--; } } } /* Currently only supports printing vector with depth 2 */ void printVectorMatrix(vector *vv, void (*printFunc)(vector *v, void *p)) { printf("[\n"); for (int i = 0; i < vv->size; i++) { vector *v = (vector *)vv->data[i]; printf(" ["); for (int j = 0; j < v->size; j++) { printFunc(v, v->data[j]); if (j != v->size - 1) printf(","); } printf("],"); printf("\n"); } printf("]\n"); } #ifdef __cplusplus } #endif #endif // VECTOR_H