From 648d68f66d55f99245254f56cef199fd27c572c4 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sat, 23 Nov 2024 23:43:03 +0300 Subject: [PATCH 01/19] Homework 9 - task 1 (WIP) --- CMakeLists.txt | 1 + homework_9/CMakeLists.txt | 5 ++ homework_9/task_1/.gitignore | 1 + homework_9/task_1/CMakeLists.txt | 9 +++ homework_9/task_1/frequencyList.c | 97 +++++++++++++++++++++++++++++ homework_9/task_1/frequencyList.h | 27 ++++++++ homework_9/task_1/frequencyLookup.c | 95 ++++++++++++++++++++++++++++ homework_9/task_1/frequencyLookup.h | 13 ++++ homework_9/task_1/main.c | 21 +++++++ homework_9/task_1/test.c | 52 ++++++++++++++++ 10 files changed, 321 insertions(+) create mode 100644 homework_9/CMakeLists.txt create mode 100644 homework_9/task_1/.gitignore create mode 100644 homework_9/task_1/CMakeLists.txt create mode 100644 homework_9/task_1/frequencyList.c create mode 100644 homework_9/task_1/frequencyList.h create mode 100644 homework_9/task_1/frequencyLookup.c create mode 100644 homework_9/task_1/frequencyLookup.h create mode 100644 homework_9/task_1/main.c create mode 100644 homework_9/task_1/test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b49a297..7a1138a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,3 +7,4 @@ set(CMAKE_C_STANDARD_REQUIRED TRUE) add_compile_options(-Wall -Wextra) add_subdirectory(homework_2) +add_subdirectory(homework_9) diff --git a/homework_9/CMakeLists.txt b/homework_9/CMakeLists.txt new file mode 100644 index 0000000..0fa5d1f --- /dev/null +++ b/homework_9/CMakeLists.txt @@ -0,0 +1,5 @@ +project(homework_9) + +set(homeworkName "${PROJECT_NAME}") + +add_subdirectory(task_1) diff --git a/homework_9/task_1/.gitignore b/homework_9/task_1/.gitignore new file mode 100644 index 0000000..06c798b --- /dev/null +++ b/homework_9/task_1/.gitignore @@ -0,0 +1 @@ +input.txt diff --git a/homework_9/task_1/CMakeLists.txt b/homework_9/task_1/CMakeLists.txt new file mode 100644 index 0000000..071dedb --- /dev/null +++ b/homework_9/task_1/CMakeLists.txt @@ -0,0 +1,9 @@ +project("${homeworkName}_task_1") + +add_library(frequencyLookup frequencyList.c frequencyLookup.c) + +add_executable(${PROJECT_NAME} main.c) +target_link_libraries(${PROJECT_NAME} frequencyLookup) + +add_executable(${PROJECT_NAME}_test test.c) +target_link_libraries(${PROJECT_NAME}_test frequencyLookup) diff --git a/homework_9/task_1/frequencyList.c b/homework_9/task_1/frequencyList.c new file mode 100644 index 0000000..a4d8f2f --- /dev/null +++ b/homework_9/task_1/frequencyList.c @@ -0,0 +1,97 @@ +#include "frequencyList.h" + +#include +#include +#include + +typedef struct FrequencyElement { + char *string; + int frequency; + FrequencyElement *next; +} FrequencyElement; + +typedef struct FrequencyList { + FrequencyElement *first; + FrequencyElement *last; + int length; +} FrequencyList; + +bool createFrequencyList(FrequencyList **list) { + *list = malloc(sizeof(FrequencyList)); + + if (*list == NULL) { + return false; + } + + (*list)->first = NULL; + (*list)->last = NULL; + (*list)->length = 0; + + return true; +} + +FrequencyElement *getFirstElement(FrequencyList *list) { + return list->first; +} + +FrequencyElement *addNewElement(FrequencyList *list) { + FrequencyElement *element = malloc(sizeof(FrequencyElement)); + if (element == NULL) { + return NULL; + } + + element->string = NULL; + element->frequency = 0; + + element->next = NULL; + if (list->first == NULL) { + list->first = element; + list->last = element; + list->length = 1; + return element; + } + + list->last->next = element; + list->last = element; + + ++list->length; + + return element; +} + +int getLength(FrequencyList *list) { + return list->length; +} + +void disposeList(FrequencyList *list) { + FrequencyElement *element = list->first; + while (element != NULL) { + FrequencyElement *next = element->next; + free(element->string); + free(element); + element = next; + } + + free(list); +} + +FrequencyElement *getNextElement(FrequencyElement *element) { + return element->next; +} + +const char *getString(FrequencyElement *element) { + return element->string; +} + +int getFrequency(FrequencyElement *element) { + return element->frequency; +} + +void setString(FrequencyElement *element, const char *string) { + free(element->string); + element->string = strdup(string); +} + +void setFrequency(FrequencyElement *element, int frequency) { + element->frequency = frequency; +} diff --git a/homework_9/task_1/frequencyList.h b/homework_9/task_1/frequencyList.h new file mode 100644 index 0000000..c91c716 --- /dev/null +++ b/homework_9/task_1/frequencyList.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +typedef struct FrequencyElement FrequencyElement; + +typedef struct FrequencyList FrequencyList; + +bool createFrequencyList(FrequencyList **list); + +FrequencyElement *getFirstElement(FrequencyList *list); + +FrequencyElement *addNewElement(FrequencyList *list); + +int getLength(FrequencyList *list); + +void disposeList(FrequencyList *list); + +FrequencyElement *getNextElement(FrequencyElement *element); + +const char *getString(FrequencyElement *element); + +int getFrequency(FrequencyElement *element); + +void setString(FrequencyElement *element, const char *string); + +void setFrequency(FrequencyElement *element, int frequency); diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c new file mode 100644 index 0000000..8c705e6 --- /dev/null +++ b/homework_9/task_1/frequencyLookup.c @@ -0,0 +1,95 @@ +#include "frequencyLookup.h" + +#include +#include +#include + +#include "frequencyList.h" + +typedef struct FrequencyLookup { + FrequencyList **buckets; + int capacity; +} FrequencyLookup; + +bool createLookup(FrequencyLookup **lookup) { + FrequencyLookup *newLookup = malloc(sizeof(FrequencyLookup)); + + if (newLookup == NULL) { + return false; + } + + newLookup->capacity = 64; + newLookup->buckets = malloc(sizeof(FrequencyList *) * newLookup->capacity); + + bool failed = false; + for (int i = 0; i < newLookup->capacity; ++i) { + if (!createFrequencyList(&(newLookup->buckets[i]))) { + failed = true; + break; + } + } + + if (failed) { + disposeLookup(newLookup); + return false; + } + + *lookup = newLookup; + return true; +} + +static unsigned int getStringHash(const char *string) { + unsigned int hash = 0; + for (int i = 0; string[i] != '\0'; ++i) { + hash = hash * 57 + string[i]; + } + return hash; +} + +// adds or creates new element +bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency) { + int bucketIndex = getStringHash(string) % lookup->capacity; + FrequencyList *bucket = lookup->buckets[bucketIndex]; + FrequencyElement *element = getFirstElement(bucket); + + while (element != NULL) { + const char *elementString = getString(element); + if (strcmp(string, elementString) == 0) { + setFrequency(element, frequency); + return true; + } + element = getNextElement(element); + } + + element = addNewElement(bucket); + if (element == NULL) { + return false; + } + setString(element, string); + setFrequency(element, frequency); + return true; +} + +bool getFrequencyByString(FrequencyLookup *lookup, const char *string, int *frequency) { + int bucketIndex = getStringHash(string) % lookup->capacity; + FrequencyList *bucket = lookup->buckets[bucketIndex]; + FrequencyElement *element = getFirstElement(bucket); + + while (element != NULL) { + const char *elementString = getString(element); + if (strcmp(string, elementString) == 0) { + *frequency = getFrequency(element); + return true; + } + element = getNextElement(element); + } + + return false; +} + +void disposeLookup(FrequencyLookup *lookup) { + for (int i = 0; i < lookup->capacity; ++i) { + disposeList(lookup->buckets[i]); + } + free(lookup); +} diff --git a/homework_9/task_1/frequencyLookup.h b/homework_9/task_1/frequencyLookup.h new file mode 100644 index 0000000..b514caf --- /dev/null +++ b/homework_9/task_1/frequencyLookup.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +typedef struct FrequencyLookup FrequencyLookup; + +bool createLookup(FrequencyLookup **lookup); + +bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency); + +bool getFrequencyByString(FrequencyLookup *lookup, const char *string, int *frequency); + +void disposeLookup(FrequencyLookup *lookup); diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c new file mode 100644 index 0000000..3dcb97c --- /dev/null +++ b/homework_9/task_1/main.c @@ -0,0 +1,21 @@ +#include + +#include "frequencyLookup.h" + +int main(void) { + FILE *file = fopen("input.txt", "r"); + if (file == NULL) { + printf("couldn't open file\n"); + return 1; + } + + FrequencyLookup *lookup = NULL; + if (!createLookup(&lookup)) { + printf("allocation error\n"); + return 1; + } + + disposeLookup(lookup); + + fclose(file); +} diff --git a/homework_9/task_1/test.c b/homework_9/task_1/test.c new file mode 100644 index 0000000..d5b3cdc --- /dev/null +++ b/homework_9/task_1/test.c @@ -0,0 +1,52 @@ +#define CTEST_MAIN +#define CTEST_SEGFAULT +#include "../../ctest/ctest.h" + +#include + +#include "frequencyLookup.h" + +int main(int argc, const char *argv[]) { + return ctest_main(argc, argv); +} + +FrequencyLookup *createNewLookup(void) { + FrequencyLookup *lookup = NULL; + ASSERT_TRUE(createLookup(&lookup)); + return lookup; +} + +CTEST(lookupTests, createTest) { + FrequencyLookup *lookup = createNewLookup(); + disposeLookup(lookup); +} + +CTEST(lookupTests, addSomeValues) { +#define size 10 + char *strings[size] = { "abc", "def", "ghi", "testString", "testString2", "qwertyuiop", "asdfghjkl", "zxcvbnm", "0123456789", "abcdefghijklmnopqrstuvwxyz" }; + int frequencies[size] = { 12, 542, 1, 4, 61, 234, 101, 456, 789, 42 }; + + FrequencyLookup *lookup = createNewLookup(); + + for (int i = 0; i < size; ++i) { + ASSERT_TRUE(addFrequency(lookup, strings[i], frequencies[i])); + + int frequency = 0; + ASSERT_TRUE(getFrequencyByString(lookup, strings[i], &frequency)); + ASSERT_EQUAL(frequency, frequencies[i]); + } + + for (int i = 0; i < size; ++i) { + int frequency = 0; + ASSERT_TRUE(getFrequencyByString(lookup, strings[i], &frequency)); + + int newFrequency = frequency * 11; + ASSERT_TRUE(addFrequency(lookup, strings[i], newFrequency)); + + ASSERT_TRUE(getFrequencyByString(lookup, strings[i], &frequency)); + ASSERT_EQUAL(frequency, newFrequency); + } + + disposeLookup(lookup); +#undef size +} From 5a7931caaa1ef987e8f72f3b2e829d56a976e913 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:02:12 +0300 Subject: [PATCH 02/19] Added hashtable expansion and iterator (hw9 task 1) --- homework_9/task_1/frequencyLookup.c | 140 +++++++++++++++++++++++++++- homework_9/task_1/frequencyLookup.h | 18 ++++ 2 files changed, 154 insertions(+), 4 deletions(-) diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index 8c705e6..77964cb 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -2,6 +2,7 @@ #include #include +#include #include #include "frequencyList.h" @@ -9,16 +10,24 @@ typedef struct FrequencyLookup { FrequencyList **buckets; int capacity; + int count; } FrequencyLookup; -bool createLookup(FrequencyLookup **lookup) { +typedef struct LookupIterator { + FrequencyLookup *lookup; + int bucketIndex; + FrequencyElement *currentElement; +} LookupIterator; + +static bool createLookupInternal(FrequencyLookup **lookup, int capacity) { FrequencyLookup *newLookup = malloc(sizeof(FrequencyLookup)); if (newLookup == NULL) { return false; } - newLookup->capacity = 64; + newLookup->count = 0; + newLookup->capacity = capacity; newLookup->buckets = malloc(sizeof(FrequencyList *) * newLookup->capacity); bool failed = false; @@ -38,6 +47,10 @@ bool createLookup(FrequencyLookup **lookup) { return true; } +bool createLookup(FrequencyLookup **lookup) { + return createLookupInternal(lookup, 64); +} + static unsigned int getStringHash(const char *string) { unsigned int hash = 0; for (int i = 0; string[i] != '\0'; ++i) { @@ -46,8 +59,61 @@ static unsigned int getStringHash(const char *string) { return hash; } +static void disposeBuckets(FrequencyLookup *lookup) { + for (int i = 0; i < lookup->capacity; ++i) { + disposeList(lookup->buckets[i]); + } +} + +static bool expandLookup(FrequencyLookup *lookup) { + int minBucketLength = getMinBucketLength(lookup); + int maxBucketLength = getMaxBucketLength(lookup); + printf("before expanding:\n"); + printf("old: [capacity: %d, min length: %d, max length: %d]\n", lookup->capacity, minBucketLength, maxBucketLength); + printf("old [occup: %lf]\n", (float)lookup->count / lookup->capacity); + + int newCapacity = lookup->capacity * 4; + + FrequencyLookup *newLookup = NULL; + if (!createLookupInternal(&newLookup, newCapacity)) { + return false; + } + + LookupIterator *iterator = getIterator(lookup); + while (moveNext(iterator)) { + const char *string = NULL; + int frequency = 0; + getCurrent(iterator, &string, &frequency); + + if (!addFrequency(newLookup, string, frequency)) { + return false; + } + } + disposeIterator(iterator); + + disposeBuckets(lookup); + + // copy new lookup to old one + *lookup = *newLookup; + + // free(), because disposeLookup() will dispose buckets + free(newLookup); + + minBucketLength = getMinBucketLength(lookup); + maxBucketLength = getMaxBucketLength(lookup); + printf("expanded lookup;\n"); + printf("new: [capacity: %d, min length: %d, max length: %d]\n", lookup->capacity, minBucketLength, maxBucketLength); + printf("new [occup: %lf]\n", (float)lookup->count / lookup->capacity); + + return true; +} + // adds or creates new element bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency) { + if ((float)lookup->count / lookup->capacity > 4.0) { + expandLookup(lookup); + } + int bucketIndex = getStringHash(string) % lookup->capacity; FrequencyList *bucket = lookup->buckets[bucketIndex]; FrequencyElement *element = getFirstElement(bucket); @@ -65,6 +131,8 @@ bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency) { if (element == NULL) { return false; } + + ++lookup->count; setString(element, string); setFrequency(element, frequency); return true; @@ -87,9 +155,73 @@ bool getFrequencyByString(FrequencyLookup *lookup, const char *string, int *freq return false; } -void disposeLookup(FrequencyLookup *lookup) { +LookupIterator *getIterator(FrequencyLookup *lookup) { + LookupIterator *iterator = malloc(sizeof(LookupIterator)); + if (iterator == NULL) { + return NULL; + } + + iterator->lookup = lookup; + iterator->bucketIndex = -1; + iterator->currentElement = NULL; + + return iterator; +} + +int getCount(FrequencyLookup *lookup) { + return lookup->count; +} + +int getCapacity(FrequencyLookup *lookup) { + return lookup->capacity; +} + +int getMinBucketLength(FrequencyLookup *lookup) { + int length = -1; for (int i = 0; i < lookup->capacity; ++i) { - disposeList(lookup->buckets[i]); + int bucketLength = getLength(lookup->buckets[i]); + if (length == -1 || bucketLength < length) { + length = bucketLength; + } + } + return length; +} + +int getMaxBucketLength(FrequencyLookup *lookup) { + int length = -1; + for (int i = 0; i < lookup->capacity; ++i) { + int bucketLength = getLength(lookup->buckets[i]); + if (length == -1 || bucketLength > length) { + length = bucketLength; + } } + return length; +} + +void disposeLookup(FrequencyLookup *lookup) { + disposeBuckets(lookup); free(lookup); } + +bool moveNext(LookupIterator *iterator) { + while (iterator->currentElement == NULL) { + ++iterator->bucketIndex; + if (iterator->bucketIndex >= iterator->lookup->capacity) { + return false; + } + iterator->currentElement = getFirstElement(iterator->lookup->buckets[iterator->bucketIndex]); + } + + return true; +} + +void getCurrent(LookupIterator *iterator, const char **string, int *frequency) { + *string = getString(iterator->currentElement); + *frequency = getFrequency(iterator->currentElement); + + iterator->currentElement = getNextElement(iterator->currentElement); +} + +void disposeIterator(LookupIterator *iterator) { + free(iterator); +} diff --git a/homework_9/task_1/frequencyLookup.h b/homework_9/task_1/frequencyLookup.h index b514caf..91bbfe4 100644 --- a/homework_9/task_1/frequencyLookup.h +++ b/homework_9/task_1/frequencyLookup.h @@ -4,10 +4,28 @@ typedef struct FrequencyLookup FrequencyLookup; +typedef struct LookupIterator LookupIterator; + bool createLookup(FrequencyLookup **lookup); bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency); bool getFrequencyByString(FrequencyLookup *lookup, const char *string, int *frequency); +LookupIterator *getIterator(FrequencyLookup *lookup); + +int getCount(FrequencyLookup *lookup); + +int getCapacity(FrequencyLookup *lookup); + +int getMinBucketLength(FrequencyLookup *lookup); + +int getMaxBucketLength(FrequencyLookup *lookup); + void disposeLookup(FrequencyLookup *lookup); + +bool moveNext(LookupIterator *iterator); + +void getCurrent(LookupIterator *iterator, const char **string, int *frequency); + +void disposeIterator(LookupIterator *iterator); From b5af9748958bc9a444ba3d4fc9b8dde9d200aca8 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:02:38 +0300 Subject: [PATCH 03/19] Added reading from file (hw9 task 1) --- homework_9/task_1/main.c | 184 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 3dcb97c..f2851a5 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -1,7 +1,126 @@ #include +#include +#include #include "frequencyLookup.h" +int readNextUTF8(FILE *stream) { + int c = fgetc(stream); + if (c == EOF) { + return EOF; + } + + if (c < 0b1'0000000) { + return c; + } + + int expectedLength = 0; + int result = EOF; + if ((c >> 5) == 0b110) { + expectedLength = 1; + result = c & 0b000'11111; + } else if ((c >> 4) == 0b1110) { + expectedLength = 2; + result = c & 0b0000'1111; + } else if ((c >> 3) == 0b11110) { + expectedLength = 3; + result = c & 0b00000'111; + } else { + return EOF; + } + + for (int i = 0; i < expectedLength; ++i) { + result <<= 6; + c = fgetc(stream); + if (c == EOF) { + return EOF; + } + if ((c >> 6) != 0b10) { + return EOF; + } + + result |= (c & 0b00'111111); + } + + return result; +} + +void writeToBuffer(int utfChar, char *buffer, int *bufferIndex, int bufferLength) { + if (*bufferIndex >= bufferLength) { + return; + } + + if (utfChar >= 0x0000 && utfChar <= 0x007F) { + buffer[*bufferIndex] = utfChar; + ++(*bufferIndex); + return; + } + + int byteLength = 0; + if (utfChar >= 0x0080 && utfChar <= 0x07FF) { + byteLength = 1; + buffer[*bufferIndex] = 0b110'00000 | ((utfChar >> 6) & 0b000'11111); + } else if (utfChar >= 0x0800 && utfChar <= 0xFFFF) { + byteLength = 2; + buffer[*bufferIndex] = 0b1110'0000 | ((utfChar >> 12) & 0b000'11111); + } else if (utfChar >= 0x10000 && utfChar <= 0x10FFFF) { + byteLength = 3; + buffer[*bufferIndex] = 0b11110'000 | ((utfChar >> 18) & 0b000'11111); + } + ++(*bufferIndex); + + for (int i = byteLength - 1; i >= 0; --i) { + if (*bufferIndex >= bufferLength) { + return; + } + + buffer[*bufferIndex] = 0b10'000000 | ((utfChar >> i * 6) & 0b00'111111); + ++(*bufferIndex); + } +} + +int partition(const char **strings, int *frequencies, int left, int right) { + if (left >= right) { + return left; + } + + int pivot = frequencies[left]; + --left; + ++right; + while (true) { + do { + ++left; + } while (frequencies[left] < pivot); + do { + --right; + } while (frequencies[right] > pivot); + + if (left >= right) { + break; + } + + int frequency = frequencies[left]; + frequencies[left] = frequencies[right]; + frequencies[right] = frequency; + + const char *string = strings[left]; + strings[left] = strings[right]; + strings[right] = string; + } + + return right; +} + +void sortStrings(const char **strings, int *frequencies, int left, int right) { + if (left >= right) { + return; + } + + int part = partition(strings, frequencies, left, right); + sortStrings(strings, frequencies, left, part); + sortStrings(strings, frequencies, part + 1, right); +} + int main(void) { FILE *file = fopen("input.txt", "r"); if (file == NULL) { @@ -15,6 +134,71 @@ int main(void) { return 1; } + char buffer[1024] = { '\0' }; + int bufferIndex = 0; + while (!feof(file)) { + int utfChar = readNextUTF8(file); + + if ((utfChar >= 0x41 && utfChar <= 0x5A) || // A-Z + (utfChar >= 0x61 && utfChar <= 0x7A) || // a-z + (utfChar >= 0x0410 && utfChar <= 0x04FF) || // А-Я + а-я + (utfChar == 0x0401 || utfChar == 0x0451)) { // Ё + ё + writeToBuffer(utfChar, buffer, &bufferIndex, sizeof(buffer)); + } else { + if (bufferIndex == 0) { + continue; + } + + int frequency = -1; + if (!getFrequencyByString(lookup, buffer, &frequency)) { + frequency = 0; + } + ++frequency; + addFrequency(lookup, buffer, frequency); + memset(buffer, 0, sizeof(buffer)); + bufferIndex = 0; + } + } + + int count = getCount(lookup); + printf("count: %d\n", count); + + int capacity = getCapacity(lookup); + int minBucketLength = getMinBucketLength(lookup); + int maxBucketLength = getMaxBucketLength(lookup); + printf("capacity: %d, min length: %d, max length: %d]\n", capacity, minBucketLength, maxBucketLength); + printf("occup: %lf\n", (float)count / capacity); + + const char **strings = malloc(sizeof(char *) * count); + int *frequencies = malloc(sizeof(int) * count); + + LookupIterator *iterator = getIterator(lookup); + int index = 0; + while (moveNext(iterator)) { + const char *string = NULL; + int frequency = 0; + getCurrent(iterator, &string, &frequency); + + strings[index] = string; + frequencies[index] = frequency; + ++index; + } + + sortStrings(strings, frequencies, 0, count - 1); + + printf("words:\n"); + + for (int i = 0; i < count; ++i) { + int j = count - i - 1; + printf("%s : %d\n", strings[j], frequencies[j]); + + if (i >= 20) { + break; + } + } + + disposeIterator(iterator); + disposeLookup(lookup); fclose(file); From d8bcd606bf7c5aa5ba5d717e70545f9c8fa1b2f9 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:03:54 +0300 Subject: [PATCH 04/19] Removed debug printing and a comment (hw9 task 1) --- homework_9/task_1/frequencyLookup.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index 77964cb..f1a7698 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -66,12 +66,6 @@ static void disposeBuckets(FrequencyLookup *lookup) { } static bool expandLookup(FrequencyLookup *lookup) { - int minBucketLength = getMinBucketLength(lookup); - int maxBucketLength = getMaxBucketLength(lookup); - printf("before expanding:\n"); - printf("old: [capacity: %d, min length: %d, max length: %d]\n", lookup->capacity, minBucketLength, maxBucketLength); - printf("old [occup: %lf]\n", (float)lookup->count / lookup->capacity); - int newCapacity = lookup->capacity * 4; FrequencyLookup *newLookup = NULL; @@ -99,16 +93,9 @@ static bool expandLookup(FrequencyLookup *lookup) { // free(), because disposeLookup() will dispose buckets free(newLookup); - minBucketLength = getMinBucketLength(lookup); - maxBucketLength = getMaxBucketLength(lookup); - printf("expanded lookup;\n"); - printf("new: [capacity: %d, min length: %d, max length: %d]\n", lookup->capacity, minBucketLength, maxBucketLength); - printf("new [occup: %lf]\n", (float)lookup->count / lookup->capacity); - return true; } -// adds or creates new element bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency) { if ((float)lookup->count / lookup->capacity > 4.0) { expandLookup(lookup); From d0d52c52360fe39250a7a86a77de79f5add9df5e Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:04:36 +0300 Subject: [PATCH 05/19] Removed trailing space (hw9 task 1) --- homework_9/task_1/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index f2851a5..0b25971 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -79,7 +79,7 @@ void writeToBuffer(int utfChar, char *buffer, int *bufferIndex, int bufferLength } } -int partition(const char **strings, int *frequencies, int left, int right) { +int partition(const char **strings, int *frequencies, int left, int right) { if (left >= right) { return left; } From 0885885476d1764913dd14da8448dc239cf1be0e Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:20:34 +0300 Subject: [PATCH 06/19] Removed utf8 support -> now word is string without space characters (hw9 task 1) --- homework_9/task_1/main.c | 92 ++++------------------------------------ 1 file changed, 9 insertions(+), 83 deletions(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 0b25971..caf2238 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -4,81 +4,6 @@ #include "frequencyLookup.h" -int readNextUTF8(FILE *stream) { - int c = fgetc(stream); - if (c == EOF) { - return EOF; - } - - if (c < 0b1'0000000) { - return c; - } - - int expectedLength = 0; - int result = EOF; - if ((c >> 5) == 0b110) { - expectedLength = 1; - result = c & 0b000'11111; - } else if ((c >> 4) == 0b1110) { - expectedLength = 2; - result = c & 0b0000'1111; - } else if ((c >> 3) == 0b11110) { - expectedLength = 3; - result = c & 0b00000'111; - } else { - return EOF; - } - - for (int i = 0; i < expectedLength; ++i) { - result <<= 6; - c = fgetc(stream); - if (c == EOF) { - return EOF; - } - if ((c >> 6) != 0b10) { - return EOF; - } - - result |= (c & 0b00'111111); - } - - return result; -} - -void writeToBuffer(int utfChar, char *buffer, int *bufferIndex, int bufferLength) { - if (*bufferIndex >= bufferLength) { - return; - } - - if (utfChar >= 0x0000 && utfChar <= 0x007F) { - buffer[*bufferIndex] = utfChar; - ++(*bufferIndex); - return; - } - - int byteLength = 0; - if (utfChar >= 0x0080 && utfChar <= 0x07FF) { - byteLength = 1; - buffer[*bufferIndex] = 0b110'00000 | ((utfChar >> 6) & 0b000'11111); - } else if (utfChar >= 0x0800 && utfChar <= 0xFFFF) { - byteLength = 2; - buffer[*bufferIndex] = 0b1110'0000 | ((utfChar >> 12) & 0b000'11111); - } else if (utfChar >= 0x10000 && utfChar <= 0x10FFFF) { - byteLength = 3; - buffer[*bufferIndex] = 0b11110'000 | ((utfChar >> 18) & 0b000'11111); - } - ++(*bufferIndex); - - for (int i = byteLength - 1; i >= 0; --i) { - if (*bufferIndex >= bufferLength) { - return; - } - - buffer[*bufferIndex] = 0b10'000000 | ((utfChar >> i * 6) & 0b00'111111); - ++(*bufferIndex); - } -} - int partition(const char **strings, int *frequencies, int left, int right) { if (left >= right) { return left; @@ -121,6 +46,10 @@ void sortStrings(const char **strings, int *frequencies, int left, int right) { sortStrings(strings, frequencies, part + 1, right); } +bool isNonWord(char c) { + return c == ' ' || c == EOF || c == '\n' || c == '\r'; +} + int main(void) { FILE *file = fopen("input.txt", "r"); if (file == NULL) { @@ -137,14 +66,8 @@ int main(void) { char buffer[1024] = { '\0' }; int bufferIndex = 0; while (!feof(file)) { - int utfChar = readNextUTF8(file); - - if ((utfChar >= 0x41 && utfChar <= 0x5A) || // A-Z - (utfChar >= 0x61 && utfChar <= 0x7A) || // a-z - (utfChar >= 0x0410 && utfChar <= 0x04FF) || // А-Я + а-я - (utfChar == 0x0401 || utfChar == 0x0451)) { // Ё + ё - writeToBuffer(utfChar, buffer, &bufferIndex, sizeof(buffer)); - } else { + int c = fgetc(file); + if (bufferIndex >= (int)sizeof(buffer) || isNonWord(c)) { if (bufferIndex == 0) { continue; } @@ -157,6 +80,9 @@ int main(void) { addFrequency(lookup, buffer, frequency); memset(buffer, 0, sizeof(buffer)); bufferIndex = 0; + } else { + buffer[bufferIndex] = c; + ++bufferIndex; } } From 107fb5db2090cd98e6238a38dfea0a7fe1f6f969 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:30:27 +0300 Subject: [PATCH 07/19] Moved disposeIterator() right after iteration (hw9 task 1) --- homework_9/task_1/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index caf2238..24d1969 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -109,6 +109,7 @@ int main(void) { frequencies[index] = frequency; ++index; } + disposeIterator(iterator); sortStrings(strings, frequencies, 0, count - 1); @@ -123,8 +124,6 @@ int main(void) { } } - disposeIterator(iterator); - disposeLookup(lookup); fclose(file); From fa6d971fd1756b3a1218082be8cce39c90d7ddcf Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:32:34 +0300 Subject: [PATCH 08/19] Made ouput less ambiguous (hw9 task 1) --- homework_9/task_1/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 24d1969..90ef958 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -87,13 +87,13 @@ int main(void) { } int count = getCount(lookup); - printf("count: %d\n", count); + printf("word count: %d\n", count); int capacity = getCapacity(lookup); int minBucketLength = getMinBucketLength(lookup); int maxBucketLength = getMaxBucketLength(lookup); - printf("capacity: %d, min length: %d, max length: %d]\n", capacity, minBucketLength, maxBucketLength); - printf("occup: %lf\n", (float)count / capacity); + printf("capacity: %d, min bucket length: %d, max bucket length: %d]\n", capacity, minBucketLength, maxBucketLength); + printf("occupancy ratio: %lf\n", (float)count / capacity); const char **strings = malloc(sizeof(char *) * count); int *frequencies = malloc(sizeof(int) * count); From 93435d4690da43354f48015bce9f6e286fa444bd Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:35:02 +0300 Subject: [PATCH 09/19] Removed strings count limit in ouput and added quotes for strings (hw9 task 1) --- homework_9/task_1/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 90ef958..31760b3 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -117,11 +117,7 @@ int main(void) { for (int i = 0; i < count; ++i) { int j = count - i - 1; - printf("%s : %d\n", strings[j], frequencies[j]); - - if (i >= 20) { - break; - } + printf("\"%s\" : %d\n", strings[j], frequencies[j]); } disposeLookup(lookup); From 0256fde4f598d223bbb88b28db440c3d52b08a45 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:40:41 +0300 Subject: [PATCH 10/19] Removed strings sorting (hw9 task 1) --- homework_9/task_1/main.c | 44 ---------------------------------------- 1 file changed, 44 deletions(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 31760b3..6a3f2a6 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -4,48 +4,6 @@ #include "frequencyLookup.h" -int partition(const char **strings, int *frequencies, int left, int right) { - if (left >= right) { - return left; - } - - int pivot = frequencies[left]; - --left; - ++right; - while (true) { - do { - ++left; - } while (frequencies[left] < pivot); - do { - --right; - } while (frequencies[right] > pivot); - - if (left >= right) { - break; - } - - int frequency = frequencies[left]; - frequencies[left] = frequencies[right]; - frequencies[right] = frequency; - - const char *string = strings[left]; - strings[left] = strings[right]; - strings[right] = string; - } - - return right; -} - -void sortStrings(const char **strings, int *frequencies, int left, int right) { - if (left >= right) { - return; - } - - int part = partition(strings, frequencies, left, right); - sortStrings(strings, frequencies, left, part); - sortStrings(strings, frequencies, part + 1, right); -} - bool isNonWord(char c) { return c == ' ' || c == EOF || c == '\n' || c == '\r'; } @@ -111,8 +69,6 @@ int main(void) { } disposeIterator(iterator); - sortStrings(strings, frequencies, 0, count - 1); - printf("words:\n"); for (int i = 0; i < count; ++i) { From edf078fe5322bc36a34f9b592e60cbe57bc957f8 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:10:15 +0300 Subject: [PATCH 11/19] Added comments (hw9 task 1) --- homework_9/task_1/frequencyList.h | 31 ++++++++++++++++++++++ homework_9/task_1/frequencyLookup.h | 41 +++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/homework_9/task_1/frequencyList.h b/homework_9/task_1/frequencyList.h index c91c716..62324b7 100644 --- a/homework_9/task_1/frequencyList.h +++ b/homework_9/task_1/frequencyList.h @@ -2,26 +2,57 @@ #include +/// @brief Element of a `FrequencyList` that contains string and frequency typedef struct FrequencyElement FrequencyElement; +/// @brief List where every element contains string and frequency typedef struct FrequencyList FrequencyList; +/// @brief Creates `FrequencyList` +/// @param list Pointer to store `FrequencyList` to +/// @return `true` if created successfully, `false` otherwise (allocation failed) bool createFrequencyList(FrequencyList **list); +/// @brief Gets first element of a list +/// @param list List to get first element from +/// @return Fist element, may be `NULL` if list is empty FrequencyElement *getFirstElement(FrequencyList *list); +/// @brief Creates new element, adds it to list, and returns it +/// @param list List to add new element to +/// @return Created element FrequencyElement *addNewElement(FrequencyList *list); +/// @brief Gets length of a list +/// @param list List to get lenght of +/// @return Length of the given list int getLength(FrequencyList *list); +/// @brief Disposes list and all of its element +/// @param list List to dispose void disposeList(FrequencyList *list); +/// @brief Gets next element of given element +/// @param element Element to get next element of +/// @return Element that follows given element, may be `NULL` FrequencyElement *getNextElement(FrequencyElement *element); +/// @brief Gets string stored in an element +/// @param element Element to get string from +/// @return String that is stored in an element const char *getString(FrequencyElement *element); +/// @brief Gets frequency stored in an element +/// @param element Element to get frequency from +/// @return Frequency that is stored in an element int getFrequency(FrequencyElement *element); +/// @brief Sets string into an element +/// @param element Element to set string into +/// @param string String to set void setString(FrequencyElement *element, const char *string); +/// @brief Sets frequency into an element +/// @param element Element to set frequency into +/// @param frequency Frequency to set void setFrequency(FrequencyElement *element, int frequency); diff --git a/homework_9/task_1/frequencyLookup.h b/homework_9/task_1/frequencyLookup.h index 91bbfe4..c518102 100644 --- a/homework_9/task_1/frequencyLookup.h +++ b/homework_9/task_1/frequencyLookup.h @@ -2,30 +2,71 @@ #include +/// @brief Lookup of frequencies, where key is string and value is int typedef struct FrequencyLookup FrequencyLookup; +/// @brief Iterator that iterates through lookup typedef struct LookupIterator LookupIterator; +/// @brief Creates `FrequencyLookup` +/// @param lookup Pointer to store `FrequencyLookup` to +/// @return `true` if created successfully, `false` otherwise (allocation failed) bool createLookup(FrequencyLookup **lookup); +/// @brief Adds new frequency to lookup or updates existing one +/// @param lookup Lookup to add frequency to +/// @param string String to add +/// @param frequency Frequency to add +/// @return `true` if added successfully, `false` otherwise (allocation failed) bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency); +/// @brief Tries to get frequency by string +/// @param lookup Lookup to get frequency from +/// @param string String to get frequency by +/// @param frequency Pointer to store frequency to +/// @return `true` if found corresponding frequency, `false otherwise` bool getFrequencyByString(FrequencyLookup *lookup, const char *string, int *frequency); +/// @brief Creates new iterator +/// @param lookup Lookup to get iterator of +/// @return New iterator LookupIterator *getIterator(FrequencyLookup *lookup); +/// @brief Gets count of entries in lookup +/// @param lookup Lookup to get count of +/// @return Count of entries int getCount(FrequencyLookup *lookup); +/// @brief Gets capacity of lookup +/// @param lookup Lookup to get capacity of +/// @return Capacity of lookup int getCapacity(FrequencyLookup *lookup); +/// @brief Gets min length of all buckets in lookup +/// @param lookup A lookup +/// @return Min length of all buckets in lookup int getMinBucketLength(FrequencyLookup *lookup); +/// @brief Gets max length of all buckets in lookup +/// @param lookup A lookup +/// @return Max length of all buckets in lookup int getMaxBucketLength(FrequencyLookup *lookup); +/// @brief Disposes lookup and all of its entries +/// @param lookup Lookup to dispose void disposeLookup(FrequencyLookup *lookup); +/// @brief Moves to next element in iterator +/// @param iterator An iterator +/// @return `true` if there are available element, `false` otherwise (end of lookup) bool moveNext(LookupIterator *iterator); +/// @brief Gets current string and frequency in iterator +/// @param iterator An iterator +/// @param string Pointer to store string to +/// @param frequency Pointer to store frequency to void getCurrent(LookupIterator *iterator, const char **string, int *frequency); +/// @brief Disposes iterator +/// @param iterator Iterator to dispose void disposeIterator(LookupIterator *iterator); From 310433d689b2b5d409de68d6facce02c1339141b Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Fri, 29 Nov 2024 20:27:12 +0300 Subject: [PATCH 12/19] Removed getMinBucketLength (hw9 task 1) --- homework_9/task_1/frequencyLookup.c | 11 ----------- homework_9/task_1/frequencyLookup.h | 5 ----- homework_9/task_1/main.c | 3 +-- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index f1a7698..5b25915 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -163,17 +163,6 @@ int getCapacity(FrequencyLookup *lookup) { return lookup->capacity; } -int getMinBucketLength(FrequencyLookup *lookup) { - int length = -1; - for (int i = 0; i < lookup->capacity; ++i) { - int bucketLength = getLength(lookup->buckets[i]); - if (length == -1 || bucketLength < length) { - length = bucketLength; - } - } - return length; -} - int getMaxBucketLength(FrequencyLookup *lookup) { int length = -1; for (int i = 0; i < lookup->capacity; ++i) { diff --git a/homework_9/task_1/frequencyLookup.h b/homework_9/task_1/frequencyLookup.h index c518102..79c626e 100644 --- a/homework_9/task_1/frequencyLookup.h +++ b/homework_9/task_1/frequencyLookup.h @@ -42,11 +42,6 @@ int getCount(FrequencyLookup *lookup); /// @return Capacity of lookup int getCapacity(FrequencyLookup *lookup); -/// @brief Gets min length of all buckets in lookup -/// @param lookup A lookup -/// @return Min length of all buckets in lookup -int getMinBucketLength(FrequencyLookup *lookup); - /// @brief Gets max length of all buckets in lookup /// @param lookup A lookup /// @return Max length of all buckets in lookup diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 6a3f2a6..ced59da 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -48,9 +48,8 @@ int main(void) { printf("word count: %d\n", count); int capacity = getCapacity(lookup); - int minBucketLength = getMinBucketLength(lookup); int maxBucketLength = getMaxBucketLength(lookup); - printf("capacity: %d, min bucket length: %d, max bucket length: %d]\n", capacity, minBucketLength, maxBucketLength); + printf("capacity: %d, max bucket length: %d]\n", capacity, maxBucketLength); printf("occupancy ratio: %lf\n", (float)count / capacity); const char **strings = malloc(sizeof(char *) * count); From 8484bad80f8c5f1d474145838b5cca87eae9c25e Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:48:53 +0300 Subject: [PATCH 13/19] Added getAverageBucketLength (hw9 task 1) --- homework_9/task_1/frequencyLookup.c | 15 +++++++++++++++ homework_9/task_1/frequencyLookup.h | 5 +++++ homework_9/task_1/main.c | 3 ++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index 5b25915..acb7ec8 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -174,6 +174,21 @@ int getMaxBucketLength(FrequencyLookup *lookup) { return length; } +float getAverageBucketLength(FrequencyLookup *lookup) { + if (lookup->capacity == 0) { + return 0; + } + + int totalLength = -1; + for (int i = 0; i < lookup->capacity; ++i) { + int bucketLength = getLength(lookup->buckets[i]); + if (bucketLength != 0) { + totalLength += bucketLength; + } + } + return (double)totalLength / lookup->capacity; +} + void disposeLookup(FrequencyLookup *lookup) { disposeBuckets(lookup); free(lookup); diff --git a/homework_9/task_1/frequencyLookup.h b/homework_9/task_1/frequencyLookup.h index 79c626e..d2d03a7 100644 --- a/homework_9/task_1/frequencyLookup.h +++ b/homework_9/task_1/frequencyLookup.h @@ -47,6 +47,11 @@ int getCapacity(FrequencyLookup *lookup); /// @return Max length of all buckets in lookup int getMaxBucketLength(FrequencyLookup *lookup); +/// @brief Gets average length of non-empty buckets in lookup +/// @param lookup A lookup +/// @return Average length of non-empty buckets in lookup +float getAverageBucketLength(FrequencyLookup *lookup); + /// @brief Disposes lookup and all of its entries /// @param lookup Lookup to dispose void disposeLookup(FrequencyLookup *lookup); diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index ced59da..23ef387 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -49,7 +49,8 @@ int main(void) { int capacity = getCapacity(lookup); int maxBucketLength = getMaxBucketLength(lookup); - printf("capacity: %d, max bucket length: %d]\n", capacity, maxBucketLength); + float averageBucketLength = getAverageBucketLength(lookup); + printf("capacity: %d, max bucket length: %d, average length of non-empty buckets: %lf]\n", capacity, maxBucketLength, averageBucketLength); printf("occupancy ratio: %lf\n", (float)count / capacity); const char **strings = malloc(sizeof(char *) * count); From ec9ddfe00ae704dddcb4b0b1cd914727130e2700 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:49:30 +0300 Subject: [PATCH 14/19] Removed unnecessary brace (hw9 task 1) --- homework_9/task_1/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index 23ef387..d453c7e 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -50,7 +50,7 @@ int main(void) { int capacity = getCapacity(lookup); int maxBucketLength = getMaxBucketLength(lookup); float averageBucketLength = getAverageBucketLength(lookup); - printf("capacity: %d, max bucket length: %d, average length of non-empty buckets: %lf]\n", capacity, maxBucketLength, averageBucketLength); + printf("capacity: %d, max bucket length: %d, average length of non-empty buckets: %lf\n", capacity, maxBucketLength, averageBucketLength); printf("occupancy ratio: %lf\n", (float)count / capacity); const char **strings = malloc(sizeof(char *) * count); From 5b39b5a360f85aae22f9987f9d9910095dae693a Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:34:49 +0300 Subject: [PATCH 15/19] Added stdbool.h include (hw9 task 1) --- homework_9/task_1/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/homework_9/task_1/main.c b/homework_9/task_1/main.c index d453c7e..f0c3b2d 100644 --- a/homework_9/task_1/main.c +++ b/homework_9/task_1/main.c @@ -1,3 +1,4 @@ +#include #include #include #include From f72669548c46d6766f2a698387fbf3bc70c8577a Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:59:37 +0300 Subject: [PATCH 16/19] Replaced stdio.h include with stdlib.h (hw9 task 1) --- homework_9/task_1/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_9/task_1/test.c b/homework_9/task_1/test.c index d5b3cdc..1676060 100644 --- a/homework_9/task_1/test.c +++ b/homework_9/task_1/test.c @@ -2,7 +2,7 @@ #define CTEST_SEGFAULT #include "../../ctest/ctest.h" -#include +#include #include "frequencyLookup.h" From ab17a10a640e5552d0698063c1ad651af691398e Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 04:02:01 +0300 Subject: [PATCH 17/19] Removed unused stdio.h include (hw9 task 1) --- homework_9/task_1/frequencyLookup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index acb7ec8..e09c3fc 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -2,7 +2,6 @@ #include #include -#include #include #include "frequencyList.h" From 1e549cda1544550124268dcea31ceeac5166ca74 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 04:05:19 +0300 Subject: [PATCH 18/19] Added null check in setString() (hw9 task 1) --- homework_9/task_1/frequencyList.c | 9 +++++++-- homework_9/task_1/frequencyList.h | 2 +- homework_9/task_1/frequencyLookup.c | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/homework_9/task_1/frequencyList.c b/homework_9/task_1/frequencyList.c index a4d8f2f..b293f98 100644 --- a/homework_9/task_1/frequencyList.c +++ b/homework_9/task_1/frequencyList.c @@ -87,9 +87,14 @@ int getFrequency(FrequencyElement *element) { return element->frequency; } -void setString(FrequencyElement *element, const char *string) { +bool setString(FrequencyElement *element, const char *string) { + char *newString = strdup(string); + if (newString == NULL) { + return false; + } free(element->string); - element->string = strdup(string); + element->string = newString; + return true; } void setFrequency(FrequencyElement *element, int frequency) { diff --git a/homework_9/task_1/frequencyList.h b/homework_9/task_1/frequencyList.h index 62324b7..d6affd4 100644 --- a/homework_9/task_1/frequencyList.h +++ b/homework_9/task_1/frequencyList.h @@ -50,7 +50,7 @@ int getFrequency(FrequencyElement *element); /// @brief Sets string into an element /// @param element Element to set string into /// @param string String to set -void setString(FrequencyElement *element, const char *string); +bool setString(FrequencyElement *element, const char *string); /// @brief Sets frequency into an element /// @param element Element to set frequency into diff --git a/homework_9/task_1/frequencyLookup.c b/homework_9/task_1/frequencyLookup.c index e09c3fc..f08a860 100644 --- a/homework_9/task_1/frequencyLookup.c +++ b/homework_9/task_1/frequencyLookup.c @@ -118,9 +118,12 @@ bool addFrequency(FrequencyLookup *lookup, const char *string, int frequency) { return false; } - ++lookup->count; - setString(element, string); + if (!setString(element, string)) { + return false; + } setFrequency(element, frequency); + + ++lookup->count; return true; } From 53e432906a564099d45822d68e34aa8b689b500e Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:36:14 +0300 Subject: [PATCH 19/19] Added README (hw9 task 1) --- homework_9/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 homework_9/README.md diff --git a/homework_9/README.md b/homework_9/README.md new file mode 100644 index 0000000..af92659 --- /dev/null +++ b/homework_9/README.md @@ -0,0 +1,3 @@ +# Homework 9 + +[Task 1. Hashtable](/homework_9/task_1)