From a4cf40603d9e3f732d7481dadb75830d7e004af6 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:54:26 +0300 Subject: [PATCH 1/6] Homework 4 task 3 --- homework_4/CMakeLists.txt | 2 + homework_4/task_3/CMakeLists.txt | 10 +++ homework_4/task_3/arrayIO.c | 34 ++++++++ homework_4/task_3/arrayIO.h | 6 ++ homework_4/task_3/frequencySearch.c | 84 ++++++++++++++++++++ homework_4/task_3/frequencySearch.h | 5 ++ homework_4/task_3/main.c | 40 ++++++++++ homework_4/task_3/test.c | 77 ++++++++++++++++++ homework_4/task_3/testFiles/emptyArray | 1 + homework_4/task_3/testFiles/incrementalArray | 8 ++ homework_4/task_3/testFiles/singleElement | 1 + 11 files changed, 268 insertions(+) create mode 100644 homework_4/task_3/CMakeLists.txt create mode 100644 homework_4/task_3/arrayIO.c create mode 100644 homework_4/task_3/arrayIO.h create mode 100644 homework_4/task_3/frequencySearch.c create mode 100644 homework_4/task_3/frequencySearch.h create mode 100644 homework_4/task_3/main.c create mode 100644 homework_4/task_3/test.c create mode 100644 homework_4/task_3/testFiles/emptyArray create mode 100644 homework_4/task_3/testFiles/incrementalArray create mode 100644 homework_4/task_3/testFiles/singleElement diff --git a/homework_4/CMakeLists.txt b/homework_4/CMakeLists.txt index 1392ccc..0099584 100644 --- a/homework_4/CMakeLists.txt +++ b/homework_4/CMakeLists.txt @@ -1,3 +1,5 @@ project(homework_4) set(homeworkName "${PROJECT_NAME}") + +add_subdirectory(task_3) diff --git a/homework_4/task_3/CMakeLists.txt b/homework_4/task_3/CMakeLists.txt new file mode 100644 index 0000000..a200aa6 --- /dev/null +++ b/homework_4/task_3/CMakeLists.txt @@ -0,0 +1,10 @@ +project("${homeworkName}_task_3") + +add_library(frequencySearch frequencySearch.c) +add_library(arrayIO arrayIO.c) + +add_executable(${PROJECT_NAME} main.c) +target_link_libraries(${PROJECT_NAME} frequencySearch arrayIO) + +add_executable(${PROJECT_NAME}_test test.c) +target_link_libraries(${PROJECT_NAME}_test PRIVATE frequencySearch arrayIO) diff --git a/homework_4/task_3/arrayIO.c b/homework_4/task_3/arrayIO.c new file mode 100644 index 0000000..16a1a48 --- /dev/null +++ b/homework_4/task_3/arrayIO.c @@ -0,0 +1,34 @@ +#include "arrayIO.h" + +#include +#include +#include + +bool readFromStream(FILE *file, int **array, int *arrayLength) { + int arrayCapacity = 4; + *arrayLength = 0; + *array = malloc(arrayCapacity * sizeof(int)); + + if (array == NULL) { + return false; + } + + while (!feof(file)) { + int value = -1; + if (fscanf(file, "%d", &value) != 1) { + continue; + } + + if (*arrayLength == arrayCapacity) { + arrayCapacity *= 2; + *array = realloc(*array, arrayCapacity * sizeof(int)); + if (*array == NULL) { + return false; + } + } + (*array)[*arrayLength] = value; + ++*arrayLength; + } + + return true; +} diff --git a/homework_4/task_3/arrayIO.h b/homework_4/task_3/arrayIO.h new file mode 100644 index 0000000..80ec6ce --- /dev/null +++ b/homework_4/task_3/arrayIO.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +bool readFromStream(FILE *file, int **array, int *arrayLength); diff --git a/homework_4/task_3/frequencySearch.c b/homework_4/task_3/frequencySearch.c new file mode 100644 index 0000000..2d457ad --- /dev/null +++ b/homework_4/task_3/frequencySearch.c @@ -0,0 +1,84 @@ +#include "frequencySearch.h" + +#include +#include + +int partition(int *array, int left, int right) { + int first = array[left], middle = array[(left + right) / 2], last = array[right]; + + int pivot = first; + if (first <= middle && middle <= last) { + pivot = middle; + } else if (middle <= first && first <= last) { + pivot = first; + } else { + pivot = last; + } + + --left; + ++right; + + while (true) { + do { + ++left; + } while (array[left] < pivot); + do { + --right; + } while (array[right] > pivot); + + if (left >= right) break; + + int t = array[left]; + array[left] = array[right]; + array[right] = t; + } + + return right; +} + +void quickSort(int *array, int left, int right) { + if (left >= right) { + return; + } + + int part = partition(array, left, right); + quickSort(array, left, part); + quickSort(array, part + 1, right); +} + +bool findMostFrequentElement(int *array, int arrayLength, int *mostFrequentElement, int *occurrences) { + if (arrayLength == 0) { + return false; + } + + quickSort(array, 0, arrayLength - 1); + + int element = array[0], count = 0; + int maxCountElement = element, maxCount = count; + + for (int i = 0; i < arrayLength; ++i) { + if (array[i] != element) { + if (count > maxCount) { + maxCount = count; + maxCountElement = element; + } + count = 0; + element = array[i]; + } + ++count; + } + + if (count > maxCount) { + maxCount = count; + maxCountElement = element; + } + + if (mostFrequentElement != NULL) { + *mostFrequentElement = maxCountElement; + } + if (occurrences != NULL) { + *occurrences = maxCount; + } + + return true; +} diff --git a/homework_4/task_3/frequencySearch.h b/homework_4/task_3/frequencySearch.h new file mode 100644 index 0000000..f087b91 --- /dev/null +++ b/homework_4/task_3/frequencySearch.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool findMostFrequentElement(int *array, int arrayLength, int *mostFrequentElement, int *occurrences); diff --git a/homework_4/task_3/main.c b/homework_4/task_3/main.c new file mode 100644 index 0000000..2c1c394 --- /dev/null +++ b/homework_4/task_3/main.c @@ -0,0 +1,40 @@ +#include +#include + +#include "frequencySearch.h" +#include "arrayIO.h" + +int main(void) { + char buffer[1024]; + printf("input file path: "); + scanf("%1023s", buffer); + + FILE *file = fopen(buffer, "r"); + if (file == NULL) { + perror("opening file failed"); + return 1; + } + + int *array; + int arrayLength; + if (!readFromStream(file, &array, &arrayLength)) { + printf("allocation error\n"); + return 1; + } + + if (ferror(file)) { + perror("read error"); + fclose(file); + return 1; + } + fclose(file); + + int mostFrequentElement, occurrences; + if (findMostFrequentElement(array, arrayLength, &mostFrequentElement, &occurrences)) { + printf("most frequent element is %d (appears %d time%s)\n", mostFrequentElement, occurrences, occurrences == 1 ? "" : "s"); + } else { + printf("couldn't find most frequent element: array is empty\n"); + } + + free(array); +} diff --git a/homework_4/task_3/test.c b/homework_4/task_3/test.c new file mode 100644 index 0000000..19f1709 --- /dev/null +++ b/homework_4/task_3/test.c @@ -0,0 +1,77 @@ +#define CTEST_MAIN +#define CTEST_SEGFAULT +#include "../../ctest/ctest.h" + +#include + +#include "frequencySearch.h" +#include "arrayIO.h" + +int main(int argc, const char *argv[]) { + return ctest_main(argc, argv); +} + +CTEST(frequencySearchTests, emptyArrayTest) { + ASSERT_FALSE(findMostFrequentElement(NULL, 0, NULL, NULL)); +} + +CTEST(frequencySearchTests, oneElementArrayTest) { +#define size 1 + int array[size] = { 42 }; + int mostFrequentExpected = 42; + int mostFrequentResult = 0; + ASSERT_TRUE(findMostFrequentElement(array, size, &mostFrequentResult, NULL)); + ASSERT_EQUAL(mostFrequentResult, mostFrequentExpected); +#undef size +} + +CTEST(frequencySearchTests, sameElementsArrayTest) { +#define size 8 + int array[size] = { 42, 42, 42, 42, 42, 42, 42, 42 }; + int mostFrequentExpected = 42, occurrencesExpected = size; + int mostFrequentResult = 0, occurrencesResult = 0; + ASSERT_TRUE(findMostFrequentElement(array, size, &mostFrequentResult, &occurrencesResult)); + ASSERT_EQUAL(mostFrequentResult, mostFrequentExpected); + ASSERT_EQUAL(occurrencesResult, occurrencesExpected); +#undef size +} + +CTEST(frequencySearchTests, constantArrayTest) { +#define size 10 + int array[size] = { 1, 2, 3, 3, 3, 7, 9, 12, 8, 3 }; + int mostFrequentExpected = 3, occurrencesExpected = 4; + int mostFrequentResult = 0, occurrencesResult = 0; + ASSERT_TRUE(findMostFrequentElement(array, size, &mostFrequentResult, &occurrencesResult)); + ASSERT_EQUAL(mostFrequentResult, mostFrequentExpected); + ASSERT_EQUAL(occurrencesResult, occurrencesExpected); +#undef size +} + +void loadFile(const char *path, int **array, int *arrayLength) { + FILE *file = fopen(path, "r"); + ASSERT_NOT_NULL(file); + ASSERT_TRUE(readFromStream(file, array, arrayLength)); + ASSERT_EQUAL(fclose(file), 0); +} + +CTEST(arrayIOTests, emptyArrayTest) { + int *array, arrayLength; + loadFile("./testFiles/emptyArray", &array, &arrayLength); + ASSERT_EQUAL(arrayLength, 0); +} + +CTEST(arrayIOTests, singleElementTest) { + int *array, arrayLength; + loadFile("./testFiles/singleElement", &array, &arrayLength); + ASSERT_EQUAL(arrayLength, 1); + ASSERT_EQUAL(array[0], 8192); +} + +CTEST(arrayIOTests, incrementalArrayTest) { + int *array, arrayLength; + loadFile("./testFiles/incrementalArray", &array, &arrayLength); + ASSERT_EQUAL(arrayLength, 8); + for (int i = 0; i < arrayLength; ++i) { + ASSERT_EQUAL(i, array[i]); + } +} diff --git a/homework_4/task_3/testFiles/emptyArray b/homework_4/task_3/testFiles/emptyArray new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/homework_4/task_3/testFiles/emptyArray @@ -0,0 +1 @@ + diff --git a/homework_4/task_3/testFiles/incrementalArray b/homework_4/task_3/testFiles/incrementalArray new file mode 100644 index 0000000..95caba1 --- /dev/null +++ b/homework_4/task_3/testFiles/incrementalArray @@ -0,0 +1,8 @@ +0 +1 +2 +3 +4 +5 +6 +7 diff --git a/homework_4/task_3/testFiles/singleElement b/homework_4/task_3/testFiles/singleElement new file mode 100644 index 0000000..252cb66 --- /dev/null +++ b/homework_4/task_3/testFiles/singleElement @@ -0,0 +1 @@ +8192 From 2c18fce65f1d5c1794ace39954d55843522aa863 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sat, 23 Nov 2024 23:16:24 +0300 Subject: [PATCH 2/6] Use scanf return value (hw4 task 3) --- homework_4/task_3/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homework_4/task_3/main.c b/homework_4/task_3/main.c index 2c1c394..d713f1e 100644 --- a/homework_4/task_3/main.c +++ b/homework_4/task_3/main.c @@ -7,7 +7,10 @@ int main(void) { char buffer[1024]; printf("input file path: "); - scanf("%1023s", buffer); + if (scanf("%1023s", buffer) != 1) { + printf("couldn't open file\n"); + return 1; + } FILE *file = fopen(buffer, "r"); if (file == NULL) { From 1d8e71aa77692200f63453ae50c3bc078548e5ec Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:12:23 +0300 Subject: [PATCH 3/6] Removed 'PRIVATE' dependency modifier (hw4 task 3) --- homework_4/task_3/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_4/task_3/CMakeLists.txt b/homework_4/task_3/CMakeLists.txt index a200aa6..dc7c8dc 100644 --- a/homework_4/task_3/CMakeLists.txt +++ b/homework_4/task_3/CMakeLists.txt @@ -7,4 +7,4 @@ add_executable(${PROJECT_NAME} main.c) target_link_libraries(${PROJECT_NAME} frequencySearch arrayIO) add_executable(${PROJECT_NAME}_test test.c) -target_link_libraries(${PROJECT_NAME}_test PRIVATE frequencySearch arrayIO) +target_link_libraries(${PROJECT_NAME}_test frequencySearch arrayIO) From 790129daef72b2fca61574458b81b5cfc38300e8 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:47:56 +0300 Subject: [PATCH 4/6] Replaced stdio.h include with stdlib.h (hw4 task 3) --- homework_4/task_3/frequencySearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_4/task_3/frequencySearch.c b/homework_4/task_3/frequencySearch.c index 2d457ad..a12b4ca 100644 --- a/homework_4/task_3/frequencySearch.c +++ b/homework_4/task_3/frequencySearch.c @@ -1,7 +1,7 @@ #include "frequencySearch.h" #include -#include +#include int partition(int *array, int left, int right) { int first = array[left], middle = array[(left + right) / 2], last = array[right]; From f41dcd54c46d02515a4f6487ca2091598e3ba5c1 Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:19:29 +0300 Subject: [PATCH 5/6] Added task name to README (hw4 task 3) --- homework_4/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homework_4/README.md b/homework_4/README.md index ca10cb8..84db32d 100644 --- a/homework_4/README.md +++ b/homework_4/README.md @@ -1 +1,3 @@ # Homework 4 + +[Task 3. Modules and files](/homework_4/task_3) From f5560e3f991b49ec162b3f6fca9438b428ac3a3a Mon Sep 17 00:00:00 2001 From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:31:15 +0300 Subject: [PATCH 6/6] Fixed library name conflict (hw4 task 3) --- homework_4/task_3/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homework_4/task_3/CMakeLists.txt b/homework_4/task_3/CMakeLists.txt index dc7c8dc..ab54a54 100644 --- a/homework_4/task_3/CMakeLists.txt +++ b/homework_4/task_3/CMakeLists.txt @@ -1,10 +1,10 @@ project("${homeworkName}_task_3") -add_library(frequencySearch frequencySearch.c) +add_library(newFrequencySearch frequencySearch.c) add_library(arrayIO arrayIO.c) add_executable(${PROJECT_NAME} main.c) -target_link_libraries(${PROJECT_NAME} frequencySearch arrayIO) +target_link_libraries(${PROJECT_NAME} newFrequencySearch arrayIO) add_executable(${PROJECT_NAME}_test test.c) -target_link_libraries(${PROJECT_NAME}_test frequencySearch arrayIO) +target_link_libraries(${PROJECT_NAME}_test newFrequencySearch arrayIO)