Created
March 23, 2022 21:49
-
-
Save johnmay/7a97b13e0fdb8473d80550b0511ea696 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <math.h> | |
typedef struct array_list | |
{ | |
char *arrayType; | |
size_t arraySize; | |
void *address; | |
size_t typeSize; | |
size_t arrayLen; | |
} Array_list; | |
char parseSizeBasedOnType(char *arrayType) | |
{ | |
if (strcmp(arrayType, "int") == 0) | |
{ | |
return sizeof(int); | |
} | |
if (strcmp(arrayType, "long") == 0) | |
{ | |
return sizeof(long long); | |
} | |
if (strcmp(arrayType, "char") == 0) | |
{ | |
return sizeof(char); | |
} | |
if (strcmp(arrayType, "char*") == 0) | |
{ | |
return sizeof(char*); | |
} | |
return 0; | |
} | |
void resizeArray(Array_list *arr) | |
{ | |
size_t newSize = arr->arraySize + (arr->arraySize>>1); | |
// or realloc() | |
void *new_cu_array = (void*)malloc(newSize*arr->typeSize); | |
memcpy(new_cu_array, arr->address, arr->arrayLen*arr->typeSize); | |
free(arr->address); | |
arr->address = new_cu_array; | |
arr->arraySize = newSize; | |
} | |
Array_list *createArray(char *arrayType, int arraySize) | |
{ | |
char sizeBasedOnType = parseSizeBasedOnType(arrayType); | |
if (sizeBasedOnType == 0) | |
{ | |
return NULL; | |
} | |
Array_list *myArray = (Array_list *)malloc(sizeof(Array_list)); | |
myArray->address = (void*)malloc(arraySize*sizeBasedOnType); | |
myArray->typeSize = sizeBasedOnType; | |
myArray->arrayType = arrayType; | |
myArray->arraySize = arraySize; | |
myArray->arrayLen = 0; | |
return myArray; | |
} | |
void push(Array_list *arr, void *data) | |
{ | |
if (arr->arrayLen == arr->arraySize) | |
{ | |
// return a bigger array | |
// create new Array_list with bigger size and copy all data to it | |
resizeArray(arr); | |
} | |
void *slot = arr->address+arr->arrayLen*arr->typeSize; | |
memcpy(slot, data, arr->typeSize); | |
arr->arrayLen = arr->arrayLen + 1; | |
} | |
void printArray(Array_list *arr) | |
{ | |
if (arr->arrayLen == 0) | |
{ | |
printf("{}\n"); | |
return; | |
} | |
const char *fmt; | |
if (strcmp(arr->arrayType, "int") == 0) | |
{ | |
for (size_t i = 0; i < arr->arrayLen; i++) | |
{ | |
printf("%d\n", ((int *)arr->address)[i]); | |
} | |
} | |
else if (strcmp(arr->arrayType, "long") == 0) | |
{ | |
for (size_t i = 0; i < arr->arrayLen; i++) | |
{ | |
printf("%llu\n", ((unsigned long long *)arr->address)[i]); | |
} | |
} | |
else if (strcmp(arr->arrayType, "char") == 0) | |
{ | |
for (size_t i = 0; i < arr->arrayLen; i++) | |
{ | |
printf("%c\n", ((char *)arr->address)[i]); | |
} | |
return; | |
} | |
else if (strcmp(arr->arrayType, "char*") == 0) | |
{ | |
for (size_t i = 0; i < arr->arrayLen; i++) | |
{ | |
printf("%s\n", ((char **)arr->address)[i]); | |
} | |
return; | |
} | |
} | |
void pop(Array_list *arr) | |
{ | |
if (arr->arrayLen == 0) | |
{ | |
return; | |
} | |
arr->arrayLen--; | |
if ((float)arr->arraySize / (float)arr->arrayLen >= 5.0) | |
{ | |
printf("old size : %zu\n", arr->arraySize); | |
arr->arraySize = (size_t)ceil((float)((arr->arraySize) / 2.0)); | |
printf("new size : %zu\n", arr->arraySize); | |
} | |
} | |
int getIndexOf(Array_list *arr, void *val) | |
{ | |
if (strcmp(arr->arrayType, "char*") == 0) | |
{ | |
for (int i = 0; i < arr->arrayLen; i++) | |
{ | |
if (strcmp(((char **)arr->address)[i], (char*)val) == 0) | |
{ | |
return i; | |
} | |
} | |
} else { | |
void *ptr = arr->address; | |
for (int i = 0; i < arr->arrayLen; i++) | |
{ | |
if (memcmp(ptr, val, arr->typeSize) == 0) | |
return i; | |
ptr += arr->typeSize; | |
} | |
} | |
return -1; | |
} | |
// use unsigned, -1 can not exist! | |
void *getElementByIndex(Array_list *arr, unsigned int index) | |
{ | |
return arr->address + index*arr->typeSize; | |
} | |
void clear(Array_list *arr) | |
{ | |
if (arr->arrayLen == 0) | |
{ | |
return; | |
} | |
free(arr->address); | |
size_t proposedNewSize = (size_t)ceil((float)arr->arrayLen / 2); | |
// at least 10 elements minimum | |
if (proposedNewSize < 10) | |
{ | |
proposedNewSize = 10; | |
} | |
arr->arraySize = proposedNewSize; | |
arr->arrayLen = 0; | |
} | |
int main() | |
{ | |
Array_list *myArr = createArray("char*", 5); | |
char *val = "hello world"; | |
push(myArr, &val); | |
val = "test test"; | |
push(myArr, &val); | |
val = "abc efg h"; | |
push(myArr, &val); | |
printArray(myArr); | |
fprintf(stderr, "index of 'abc efg h'? %d\n", getIndexOf(myArr, "abc efg h")); | |
fprintf(stderr, "index of 'hello world'? %d\n", getIndexOf(myArr, "hello world")); | |
fprintf(stderr, "index of 'blah'? %d\n", getIndexOf(myArr, "blah")); | |
fprintf(stderr, "myArr[1] = %s\n", *((char**)getElementByIndex(myArr, 1))); | |
Array_list *longArrayList = createArray("long", 1); | |
long long num; | |
num = 42; | |
push(longArrayList, &num); | |
num = 23; | |
push(longArrayList, &num); | |
num = 7; | |
push(longArrayList, &num); | |
printArray(longArrayList); | |
num = 2; | |
fprintf(stderr, "%d\n", getIndexOf(longArrayList, &num)); | |
num = 23; | |
fprintf(stderr, "%d\n", getIndexOf(longArrayList, &num)); | |
num = 42; | |
fprintf(stderr, "%d\n", getIndexOf(longArrayList, &num)); | |
fprintf(stderr, "longArrayList[1] = %lld\n", *((long long*)getElementByIndex(longArrayList, 1))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment