From 7d670a0938a16a4b2c71b0dc25d01404abce9f43 Mon Sep 17 00:00:00 2001 From: kamendov-maxim Date: Wed, 27 Dec 2023 17:16:45 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=A1=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE=D1=87=D0=BD=D0=B0=D1=8F=20=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework5/sortingStation/CMakeLists.txt | 16 +++ .../homework5/sortingStation/Stack/Stack.c | 118 ++++++++++++++++++ .../homework5/sortingStation/Stack/Stack.h | 28 +++++ .../sortingStation/getString/getString.c | 37 ++++++ .../sortingStation/getString/getString.h | 8 ++ semester_1/homework5/sortingStation/main.c | 38 ++++++ .../sortingStation/sortingStation.c | 117 +++++++++++++++++ .../sortingStation/sortingStation.h | 4 + .../homework5/sortingStation/tests/test.c | 42 +++++++ .../homework5/sortingStation/tests/test.h | 6 + 10 files changed, 414 insertions(+) create mode 100644 semester_1/homework5/sortingStation/CMakeLists.txt create mode 100644 semester_1/homework5/sortingStation/Stack/Stack.c create mode 100644 semester_1/homework5/sortingStation/Stack/Stack.h create mode 100644 semester_1/homework5/sortingStation/getString/getString.c create mode 100644 semester_1/homework5/sortingStation/getString/getString.h create mode 100644 semester_1/homework5/sortingStation/main.c create mode 100644 semester_1/homework5/sortingStation/sortingStation/sortingStation.c create mode 100644 semester_1/homework5/sortingStation/sortingStation/sortingStation.h create mode 100644 semester_1/homework5/sortingStation/tests/test.c create mode 100644 semester_1/homework5/sortingStation/tests/test.h diff --git a/semester_1/homework5/sortingStation/CMakeLists.txt b/semester_1/homework5/sortingStation/CMakeLists.txt new file mode 100644 index 0000000..8c0c6c7 --- /dev/null +++ b/semester_1/homework5/sortingStation/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.8.0) +project(sortingStation VERSION 0.1.0 LANGUAGES C) + +include(CTest) +enable_testing() + +add_executable(sortingStation main.c +sortingStation/sortingStation.c +Stack/Stack.c +getString/getString.c +tests/test.c +) + +set(CPACK_PROJECT_NAME ${PROJECT_NAME}) +set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) +include(CPack) diff --git a/semester_1/homework5/sortingStation/Stack/Stack.c b/semester_1/homework5/sortingStation/Stack/Stack.c new file mode 100644 index 0000000..b5cc4eb --- /dev/null +++ b/semester_1/homework5/sortingStation/Stack/Stack.c @@ -0,0 +1,118 @@ +#include + +#include "Stack.h" + +typedef struct Node +{ + struct Node *next; + char value; +} Node; + +typedef struct Stack +{ + size_t length; + Node *head; +} Stack; + +Stack *createStack(void) +{ + return calloc(1, sizeof(Stack)); +} + +void deleteStack(Stack **const stack) +{ + Node *currentNode = (*stack)->head; + while (currentNode != NULL) + { + Node *temp = currentNode; + currentNode = currentNode->next; + free(temp); + } + free(*stack); + *stack = NULL; +} + +StackErrorCode addElement(Stack *const stack, const char value) +{ + Node *newNode = calloc(1, sizeof(Node)); + if (newNode == NULL) + { + return memoryErrorStack; + } + newNode->value = value; + if (stack->head != NULL) + { + newNode->next = stack->head; + } + stack->head = newNode; + ++(stack->length); + + return okStack; +} + +char getElement(Stack *const stack, StackErrorCode *const errorCode) +{ + if (stack->head == NULL) + { + *errorCode = emptyStack; + return 0; + } + + Node *temp = stack->head; + stack->head = temp->next; + char value = temp->value; + free(temp); + --(stack->length); + *errorCode = okStack; + return value; +} + +char topElement(Stack const *const stack, StackErrorCode *const errorCode) +{ + if (stack->head == NULL) + { + *errorCode = emptyStack; + return '\0'; + } + *errorCode = okStack; + return stack->head->value; +} + +static void addToString(Node * const node, char * output, size_t i) +{ + if (node == NULL) + { + return; + } + + if (node->next == NULL) + { + output[i] = node->value; + output[i + 1] = ' '; + return; + } + addToString(node->next, output, i - 2); + output[i] = node->value; + output[i + 1] = ' '; +} + +char *createString(Stack const *const stack, StackErrorCode *errorCode) +{ + if (stack == NULL || stack->head == NULL) + { + *errorCode = emptyStack; + return NULL; + } + + char *output = (char *)malloc((stack->length) * 2 * sizeof(char)); + if (output == NULL) + { + *errorCode = memoryErrorStack; + return NULL; + } + size_t strl = stack->length * 2; + addToString(stack->head, output, strl - 2); + output[strl -1 ]= '\0'; + return output; +} + diff --git a/semester_1/homework5/sortingStation/Stack/Stack.h b/semester_1/homework5/sortingStation/Stack/Stack.h new file mode 100644 index 0000000..619a8c9 --- /dev/null +++ b/semester_1/homework5/sortingStation/Stack/Stack.h @@ -0,0 +1,28 @@ +#pragma once + +typedef struct Stack Stack; +typedef enum StackErrorCode +{ + okStack, + memoryErrorStack, + emptyStack +} StackErrorCode; + +// создать пустой стек +Stack *createStack(void); + +// удалить стек +void deleteStack(Stack ** const stack); + +// добавить элемент в стек +StackErrorCode addElement(Stack *const stack, const char value); + +// взять верхний элемент из стека +char getElement(Stack *const stack, StackErrorCode * const errorCode); + +// получить значение верхней ячейки стека, не удаляя ее +char topElement(Stack const *const stack, StackErrorCode *const errorCode); + +// получить строку со всеми значениями стека, где самый правый элемент - самый верхний элемент стека +char *createString(Stack const *const stack, StackErrorCode *errorCode); + diff --git a/semester_1/homework5/sortingStation/getString/getString.c b/semester_1/homework5/sortingStation/getString/getString.c new file mode 100644 index 0000000..a018a21 --- /dev/null +++ b/semester_1/homework5/sortingStation/getString/getString.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "getString.h" + +char *getString(FILE * file, char const endOfLine) +{ + size_t len = 0; + size_t capacity = 1; + char *s = (char *)malloc(sizeof(char)); + if (s == NULL) + { + return NULL; + } + + for (char c = fgetc(file); c != endOfLine && c != EOF; c = fgetc(file)) + { + s[len++] = c; + + if (len >= capacity) + { + capacity *= 2; + char *tmp = (char *)realloc(s, capacity * sizeof(char)); + if (tmp == NULL) + { + free(s); + return NULL; + } + s = tmp; + } + } + + s[len] = '\0'; + + return s; +} diff --git a/semester_1/homework5/sortingStation/getString/getString.h b/semester_1/homework5/sortingStation/getString/getString.h new file mode 100644 index 0000000..54717f8 --- /dev/null +++ b/semester_1/homework5/sortingStation/getString/getString.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include + +// получить строку из *file до разделителя endOfLine +char *getString(FILE * file, char const endOfLine); diff --git a/semester_1/homework5/sortingStation/main.c b/semester_1/homework5/sortingStation/main.c new file mode 100644 index 0000000..783605b --- /dev/null +++ b/semester_1/homework5/sortingStation/main.c @@ -0,0 +1,38 @@ +#include +#include + +#include "sortingStation/sortingStation.h" +#include "getString/getString.h" +#include "tests/test.h" + +typedef enum ExitCode +{ + programFinishedCorrectly, + programFailedTests, + memoryError + +} ExitCode; + +int main(void) +{ + setlocale(LC_ALL, "Russian"); + + if (test()) + { + printf("К сожалению, программа сейчас не работает\n"); + return programFailedTests; + } + + printf("Введите арифметическое выражение в инфиксной форме: "); + char * expression = getString(stdin, '\n'); + if (expression == NULL) + { + printf("\nНедостаточно памяти\n"); + return memoryError; + } + + printf("\nВыражение в постфиксной форме: "); + char * ex = createPostfixForm(expression); + printf("%s\n", ex); + return programFinishedCorrectly; +} diff --git a/semester_1/homework5/sortingStation/sortingStation/sortingStation.c b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c new file mode 100644 index 0000000..2683ea6 --- /dev/null +++ b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c @@ -0,0 +1,117 @@ +#include +#include +#include + +#include "../Stack/Stack.h" +#include "sortingStation.h" + +static void ignoreSpaces(char const *const expression, size_t *const counter) +{ + for (; expression[*counter] == ' '; ++(*counter)) + ; +} + +static int compareOperators(char const operator1, char const operator2) +{ + if (operator1 == '*' || operator1 == '/') + { + if (operator2 == '+' || operator2 == '-') + { + return 1; + } + return 0; + } + else + { + if (operator2 == '+' || operator2 == '-') + { + return 0; + } + return -1; + } +} + +static StackErrorCode moveToOutputStack(Stack *const outputStack, Stack *const operatorsStack) +{ + StackErrorCode ec = okStack; + for (char currentOperator = getElement(operatorsStack, &ec); + currentOperator != '(' && ec != emptyStack; currentOperator = getElement(operatorsStack, &ec)) + { + StackErrorCode ec2 = addElement(outputStack, currentOperator); + if (ec2 != okStack) + { + return ec2; + } + } + return okStack; +} + +char *createPostfixForm(char const *const infixForm) +{ + size_t len = strlen(infixForm); + size_t counter = 0; + + Stack *outputStack = createStack(); + if (outputStack == NULL) + { + return NULL; + } + Stack *operatorsStack = createStack(); + if (operatorsStack == NULL) + { + deleteStack(&outputStack); + return NULL; + } + + StackErrorCode ec = okStack; + + for (size_t i = 0; i < len; ++i) + { + ignoreSpaces(infixForm, &i); + if (i >= len) + { + break; + } + char currentChar = infixForm[i]; + if (isdigit(currentChar)) + { + ec = addElement(outputStack, infixForm[i]); + } + else if (currentChar == ')') + { + ec = moveToOutputStack(outputStack, operatorsStack); + } + else if (currentChar == '(') + { + ec = addElement(operatorsStack, currentChar); + } + else + { + char top = topElement(operatorsStack, &ec); + if (ec != okStack) + { + deleteStack(&operatorsStack); + deleteStack(&outputStack); + return NULL; + } + int comparison = compareOperators(top, currentChar); + while (ec != emptyStack && top != '(' && comparison != -1) + { + char operatorFromStack = getElement(operatorsStack, &ec); + ec = addElement(outputStack, operatorFromStack); + top = topElement(operatorsStack, &ec); + comparison = compareOperators(top, currentChar); + } + ec = addElement(operatorsStack, currentChar); + } + if (ec != okStack) + { + deleteStack(&operatorsStack); + deleteStack(&outputStack); + return NULL; + } + } + ec = moveToOutputStack(outputStack, operatorsStack); + char *output = createString(outputStack, &ec); + return output; +} diff --git a/semester_1/homework5/sortingStation/sortingStation/sortingStation.h b/semester_1/homework5/sortingStation/sortingStation/sortingStation.h new file mode 100644 index 0000000..fa3f391 --- /dev/null +++ b/semester_1/homework5/sortingStation/sortingStation/sortingStation.h @@ -0,0 +1,4 @@ +#pragma once + +// получает на вход арифметическое выражение в инфиксной форме, возвращает то же выражение в постфиксной форме +char *createPostfixForm(char const *const infixForm); diff --git a/semester_1/homework5/sortingStation/tests/test.c b/semester_1/homework5/sortingStation/tests/test.c new file mode 100644 index 0000000..1fdd284 --- /dev/null +++ b/semester_1/homework5/sortingStation/tests/test.c @@ -0,0 +1,42 @@ +#include +#include + +#include "test.h" +#include "../sortingStation/sortingStation.h" + +const bool test(void) +{ + const size_t testNumber = 6; + const char * const testExpressions[testNumber] = { + "1 + 2", + " ( 2 + 4) * 5", + " 2 + 4 * 5 ", + " 4 * 6 * 7 * 8", + "(1 + (2 - 3) + (7 / 2)) * (1 + 8)", + "1" + }; + + const char * const answers[testNumber] = { + "1 2 +", + "2 4 + 5 *", + "2 4 5 * +", + "4 6 * 7 * 8 *", + "1 2 3 - 7 2 / + 1 8 + 8" + }; + + for (size_t i = 0; i < testNumber; ++i) + { + char * expression = createPostfixForm(testExpressions[i]); + if (expression == NULL) + { + return false; + } + int comparison = strcmp(expression, answers[i]); + free(expression); + if (comparison != 0) + { + return false; + } + } + return true; +} diff --git a/semester_1/homework5/sortingStation/tests/test.h b/semester_1/homework5/sortingStation/tests/test.h new file mode 100644 index 0000000..0e483cd --- /dev/null +++ b/semester_1/homework5/sortingStation/tests/test.h @@ -0,0 +1,6 @@ +#pragma once +#include + + +// тесты для функции char *createPostfixForm(char const *const infixForm) +const bool test(void); From bdaa1a885f6e64e6aebc24b018cb785dca695ec6 Mon Sep 17 00:00:00 2001 From: kamendov-maxim Date: Wed, 27 Dec 2023 17:47:28 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=9E=D1=87=D0=B8=D1=81=D1=82=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- semester_1/homework5/sortingStation/main.c | 9 +++++++++ .../sortingStation/sortingStation/sortingStation.c | 8 ++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/semester_1/homework5/sortingStation/main.c b/semester_1/homework5/sortingStation/main.c index 783605b..b5e4910 100644 --- a/semester_1/homework5/sortingStation/main.c +++ b/semester_1/homework5/sortingStation/main.c @@ -1,5 +1,6 @@ #include #include +#include #include "sortingStation/sortingStation.h" #include "getString/getString.h" @@ -33,6 +34,14 @@ int main(void) printf("\nВыражение в постфиксной форме: "); char * ex = createPostfixForm(expression); + free(expression); + if (ex == NULL) + { + printf("\nНедостаточно памяти\n"); + return memoryError; + } + printf("%s\n", ex); + free(ex); return programFinishedCorrectly; } diff --git a/semester_1/homework5/sortingStation/sortingStation/sortingStation.c b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c index 2683ea6..d2ee189 100644 --- a/semester_1/homework5/sortingStation/sortingStation/sortingStation.c +++ b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c @@ -88,12 +88,6 @@ char *createPostfixForm(char const *const infixForm) else { char top = topElement(operatorsStack, &ec); - if (ec != okStack) - { - deleteStack(&operatorsStack); - deleteStack(&outputStack); - return NULL; - } int comparison = compareOperators(top, currentChar); while (ec != emptyStack && top != '(' && comparison != -1) { @@ -113,5 +107,7 @@ char *createPostfixForm(char const *const infixForm) } ec = moveToOutputStack(outputStack, operatorsStack); char *output = createString(outputStack, &ec); + deleteStack(&operatorsStack); + deleteStack(&outputStack); return output; } From 206bd77a131aa9ab5bdf600d360447e9ef8a29e9 Mon Sep 17 00:00:00 2001 From: kamendov-maxim Date: Wed, 27 Dec 2023 17:56:35 +0300 Subject: [PATCH 3/4] =?UTF-8?q?const,=20=D0=BF=D1=80=D0=BE=D0=B1=D0=B5?= =?UTF-8?q?=D0=BB=D1=8B,=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- semester_1/homework5/sortingStation/Stack/Stack.c | 11 +++++------ semester_1/homework5/sortingStation/Stack/Stack.h | 3 +-- .../homework5/sortingStation/getString/getString.c | 2 +- .../homework5/sortingStation/getString/getString.h | 2 +- .../sortingStation/sortingStation/sortingStation.c | 6 ++++++ 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/semester_1/homework5/sortingStation/Stack/Stack.c b/semester_1/homework5/sortingStation/Stack/Stack.c index b5cc4eb..cdf0c4c 100644 --- a/semester_1/homework5/sortingStation/Stack/Stack.c +++ b/semester_1/homework5/sortingStation/Stack/Stack.c @@ -78,22 +78,22 @@ char topElement(Stack const *const stack, StackErrorCode *const errorCode) return stack->head->value; } -static void addToString(Node * const node, char * output, size_t i) +static void addToString(Node *const node, char *output, size_t i) { if (node == NULL) { return; } - + if (node->next == NULL) { - output[i] = node->value; + output[i] = node->value; output[i + 1] = ' '; return; } addToString(node->next, output, i - 2); output[i] = node->value; - output[i + 1] = ' '; + output[i + 1] = ' '; } char *createString(Stack const *const stack, StackErrorCode *errorCode) @@ -112,7 +112,6 @@ char *createString(Stack const *const stack, StackErrorCode *errorCode) } size_t strl = stack->length * 2; addToString(stack->head, output, strl - 2); - output[strl -1 ]= '\0'; + output[strl - 1] = '\0'; return output; } - diff --git a/semester_1/homework5/sortingStation/Stack/Stack.h b/semester_1/homework5/sortingStation/Stack/Stack.h index 619a8c9..b819d71 100644 --- a/semester_1/homework5/sortingStation/Stack/Stack.h +++ b/semester_1/homework5/sortingStation/Stack/Stack.h @@ -24,5 +24,4 @@ char getElement(Stack *const stack, StackErrorCode * const errorCode); char topElement(Stack const *const stack, StackErrorCode *const errorCode); // получить строку со всеми значениями стека, где самый правый элемент - самый верхний элемент стека -char *createString(Stack const *const stack, StackErrorCode *errorCode); - +char *createString(Stack const *const stack, StackErrorCode * const errorCode); diff --git a/semester_1/homework5/sortingStation/getString/getString.c b/semester_1/homework5/sortingStation/getString/getString.c index a018a21..3f7a54f 100644 --- a/semester_1/homework5/sortingStation/getString/getString.c +++ b/semester_1/homework5/sortingStation/getString/getString.c @@ -4,7 +4,7 @@ #include "getString.h" -char *getString(FILE * file, char const endOfLine) +char *getString(FILE const * const file, char const endOfLine) { size_t len = 0; size_t capacity = 1; diff --git a/semester_1/homework5/sortingStation/getString/getString.h b/semester_1/homework5/sortingStation/getString/getString.h index 54717f8..6f21e6f 100644 --- a/semester_1/homework5/sortingStation/getString/getString.h +++ b/semester_1/homework5/sortingStation/getString/getString.h @@ -5,4 +5,4 @@ #include // получить строку из *file до разделителя endOfLine -char *getString(FILE * file, char const endOfLine); +char *getString(FILE const * const file, char const endOfLine); diff --git a/semester_1/homework5/sortingStation/sortingStation/sortingStation.c b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c index d2ee189..87a85a7 100644 --- a/semester_1/homework5/sortingStation/sortingStation/sortingStation.c +++ b/semester_1/homework5/sortingStation/sortingStation/sortingStation.c @@ -93,6 +93,12 @@ char *createPostfixForm(char const *const infixForm) { char operatorFromStack = getElement(operatorsStack, &ec); ec = addElement(outputStack, operatorFromStack); + if (ec != okStack) + { + deleteStack(&operatorsStack); + deleteStack(&outputStack); + return NULL; + } top = topElement(operatorsStack, &ec); comparison = compareOperators(top, currentChar); } From 6d3d78504e12f0b2e102fe15d71b418dbaa6e5cb Mon Sep 17 00:00:00 2001 From: kamendov-maxim Date: Wed, 27 Dec 2023 18:54:25 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=D1=80=D0=B5=D0=BA=D1=83=D1=80=D1=81=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BD=D0=B0=20=D1=86=D0=B8=D0=BA=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework5/sortingStation/Stack/Stack.c | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/semester_1/homework5/sortingStation/Stack/Stack.c b/semester_1/homework5/sortingStation/Stack/Stack.c index cdf0c4c..a318291 100644 --- a/semester_1/homework5/sortingStation/Stack/Stack.c +++ b/semester_1/homework5/sortingStation/Stack/Stack.c @@ -78,25 +78,7 @@ char topElement(Stack const *const stack, StackErrorCode *const errorCode) return stack->head->value; } -static void addToString(Node *const node, char *output, size_t i) -{ - if (node == NULL) - { - return; - } - - if (node->next == NULL) - { - output[i] = node->value; - output[i + 1] = ' '; - return; - } - addToString(node->next, output, i - 2); - output[i] = node->value; - output[i + 1] = ' '; -} - -char *createString(Stack const *const stack, StackErrorCode *errorCode) +char *createString(Stack const *const stack, StackErrorCode *const errorCode) { if (stack == NULL || stack->head == NULL) { @@ -104,14 +86,22 @@ char *createString(Stack const *const stack, StackErrorCode *errorCode) return NULL; } - char *output = (char *)malloc((stack->length) * 2 * sizeof(char)); + size_t strl = stack->length * 2; + char *output = (char *)malloc(strl * sizeof(char)); if (output == NULL) { *errorCode = memoryErrorStack; return NULL; } - size_t strl = stack->length * 2; - addToString(stack->head, output, strl - 2); + + size_t i = strl - 1; + for (Node *currentNode = stack->head; currentNode != NULL; currentNode = currentNode->next) + { + output[i - 1] = currentNode->value; + output[i] = ' '; + i -= 2; + } + output[strl - 1] = '\0'; return output; }