Added vector code and a strip function for strings.

This commit is contained in:
Aaron Helton
2019-10-09 21:56:42 -04:00
parent 03cb4f215d
commit 03b4dfe5cb
3 changed files with 195 additions and 25 deletions

View File

@@ -26,8 +26,11 @@ typedef struct NAME_STR {
string *create_from_cstr(const char *str);
void destroy_string(string *str);
string *concatenate_string(string *str, string *other);
int compare_on_length(string *str, string *other);
string *concatenate_string(const string *str, const string *other);
void strip(string *str);
int compare_on_length(const string *str, const string *other);
int compare_on_alphabet(const string *str, const string *other);
#endif

View File

@@ -1,23 +1,117 @@
#include <stdio.h>
#include <stdlib.h>
#include <name_string.h>
#define MIN_VEC_SIZE 8
//stdint guarantees the least types, unlike the standard uint32_t;
typedef uint_least32_t uint32;
//Simple vector implementation for our strings
typedef struct str_vector
{
string **array;
uint32 size;
uint32 _capacity;
} string_vector;
string_vector *create_vector(uint32 capacity)
{
if(capacity < MIN_VEC_SIZE)
{
capacity = MIN_VEC_SIZE;
}
string_vector *vec = malloc(sizeof(string_vector));
vec->array = malloc(sizeof(string *) * capacity);
vec->size = 0;
vec->_capacity = capacity;
return vec;
}
/*
* For our particular program, we don't need the ability to remove items from
* the vector, as we'll only ever be adding to it.
*/
void vector_add(string_vector *vector, string *str)
{
if(vector->size == vector->_capacity)
{
string **new_array = malloc(sizeof(string *) * vector->_capacity * 2);
for(uint32 index = 0; index < vector->_capacity; index++)
{
new_array[index] = vector->array[index];
}
free(vector->array);
vector->array = new_array;
vector->_capacity *= 2;
}
vector->array[vector->size] = str;
vector->size++;
}
void print_vector(string_vector *vector)
{
for(uint32 index = 0; index < vector->size; index++)
{
printf("%s", vector->array[index]->c_str);
}
}
/*
* Compare function to be used by qsort. Due to the implementation in the C
* Standard Library, this function necessarily accepts void * and must cast to
* the type it expects.
*/
int compare(const void *str1, const void *str2)
{
const string *first = *(const string **) str1;
const string *second = *(const string **) str2;
int res = compare_on_length(first, second);
if(res == 0)
{
return compare_on_alphabet(first, second);
}
return res;
}
/*
* Sorts the passed vector with the rules that:
* 1. Strings are sorted by length first, not alphabet.
* 2. Strings are sorted by alphabet only if they are the same length.
*/
void perform_length_alphabet_sort(string_vector *vector)
{
qsort((void *) vector->array, vector->size, sizeof(string *), compare);
}
int main(int argc, char **argv)
{
string *test = create_from_cstr("Testing");
printf("String: %s\n", test->c_str);
printf("Size expected: %d\n", 7);
printf("Actual Size: %d\n", test->len);
char *tests[10] = {
"What ",
"Where",
" When",
" Why ",
"How",
"Test1",
"Test2",
"Anne",
"Jill",
"Bob"
};
string *other = create_from_cstr("This is also a test");
string *combined = concatenate_string(test, other);
printf("First String: %s\n", test->c_str);
printf("Second String: %s\n", other->c_str);
printf("Expected: TestingThis is also a test\n");
printf("Actual: %s\n", combined->c_str);
printf("Length of first string: %d\n", test->len);
printf("Length of second string: %d\n", other->len);
printf("Expected Length: %d\n", test->len + other->len);
printf("Length of Combined String: %d\n", combined->len);
string_vector *vector = create_vector(0);
for(uint32 index = 0; index < 10; index++)
{
string *str = create_from_cstr(tests[index]);
strip(str);
vector_add(vector, str);
}
print_vector(vector);
perform_length_alphabet_sort(vector);
printf("\nSorted Array\n------------\n");
print_vector(vector);
return 0;
}

View File

@@ -7,7 +7,7 @@
string *create_from_cstr(const char *str)
{
string *new_str = (string *)malloc(sizeof(string));
string *new_str = (string *) malloc(sizeof(string));
if(!str)
{
//The passed c string is a null or invalid pointer.
@@ -24,7 +24,7 @@ string *create_from_cstr(const char *str)
}
//Make sure to +1 for the null byte at the end
new_str->c_str = (char *)malloc(sizeof(char)*size + 1);
new_str->c_str = (char *) malloc(sizeof(char) * size + 1);
for(index = 0; index < size && *str != '\0'; index++)
{
new_str->c_str[index] = str[index];
@@ -47,17 +47,21 @@ void destroy_string(string *str)
free(str);
}
string *concatenate_string(string *str, string *other)
string *concatenate_string(const string *str, const string *other)
{
if(!str || !other)
{
return NULL;
}
if(str->len + other->len > MAX_STR_SIZE)
{
return NULL;
}
strlen_t total_len = str->len + other->len;
string *new_str = (string *)malloc(sizeof(string));
new_str->c_str = (char *)malloc(sizeof(char)*total_len + 1);
string *new_str = (string *) malloc(sizeof(string));
new_str->c_str = (char *) malloc(sizeof(char) * total_len + 1);
new_str->len = total_len;
for(strlen_t index = 0; index < str->len; index++)
@@ -66,13 +70,78 @@ string *concatenate_string(string *str, string *other)
}
for(strlen_t index = 0; index < other->len; index++)
{
new_str->c_str[index+str->len] = other->c_str[index];
new_str->c_str[index + str->len] = other->c_str[index];
}
new_str->c_str[total_len] = '\0';
return new_str;
}
int compare_on_length(string *str, string *other)
static int is_whitespace(char c)
{
if(c == ' ' || c == '\t' || c == '\n' || c == '\v')
{
return 1;
}
return 0;
}
void strip(string *str)
{
//Sanity check
if(!str || !str->c_str || str->len == 0)
{
return;
}
//Strip the left side
strlen_t lstrip_index = 0;
for(strlen_t index = 0; index < str->len; index++)
{
if(is_whitespace(str->c_str[index]))
{
lstrip_index++;
}
else
{
break;
}
}
//Find right side strip index
strlen_t rstrip_index = str->len;
for(strlen_t index = str->len - 1; index >= 0; index--)
{
if(is_whitespace(str->c_str[index]))
{
rstrip_index--;
}
else
{
break;
}
}
if(lstrip_index == rstrip_index)
{
free(str->c_str);
str->c_str = NULL;
str->len = 0;
}
else
{
strlen_t chop_off = lstrip_index + (str->len - rstrip_index);
char *new = malloc(sizeof(char) * (str->len - chop_off + 1));
for(strlen_t index = lstrip_index; index < rstrip_index; index++)
{
new[index - lstrip_index] = str->c_str[index];
}
new[rstrip_index - lstrip_index] = '\0';
free(str->c_str);
str->c_str = new;
str->len -= chop_off;
}
}
int compare_on_length(const string *str, const string *other)
{
if(str->len < other->len)
{
@@ -104,10 +173,10 @@ static char lowercase(char c)
{
return c;
}
return (char)(c-32);
return (char) (c - 32);
}
int compare_on_alphabet(string *str, string *other)
int compare_on_alphabet(const string *str, const string *other)
{
strlen_t min_len = min(str->len, other->len);
for(strlen_t index = 0; index < min_len; index++)
@@ -115,9 +184,13 @@ int compare_on_alphabet(string *str, string *other)
char str_lower_char = lowercase(str->c_str[index]);
char other_lower_char = lowercase(other->c_str[index]);
if(str_lower_char < other_lower_char)
{
return -1;
}
else if(str_lower_char > other_lower_char)
{
return 1;
}
}
//Only difference is length
return compare_on_length(str, other);