diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d763d38 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,65 @@ +# Минимальная требуемая версия CMake +cmake_minimum_required(VERSION 3.10) + +# Общее название проекта +project(Homework_5 LANGUAGES C) + +# Установка стандарта языка C +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +# Включение общей библиотеки stack +add_subdirectory(src/stack) + +# =========== ПРОЕКТ 1: Проверка скобок ========== +# Включение модуля для проекта скобок +add_subdirectory(src/hw_5-1_proBrackets) + +# Создание исполняемого файла для проверки скобок +add_executable(hw_5_1_proBrackets + src/hw_5-1_proBrackets/hw_5-1_proBracketsMain.c +) + +# Связывание с библиотеками +target_link_libraries(hw_5_1_proBrackets + PRIVATE + stackLib + hw_5_1_proBracketsLib +) + +# Установка путей заголовочных файлов для proBrackets +target_include_directories(hw_5_1_proBrackets + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/stack + ${CMAKE_CURRENT_SOURCE_DIR}/src/hw_5-1_proBrackets +) + +# ========== ПРОЕКТ 2: Сортировочная станция ========== +# Включение модуля для сортировочной станции +add_subdirectory(src/hw_5-2_sortStation) + +# Создание исполняемого файла для сортировочной станции +add_executable(hw_5_2_sortStation + src/hw_5-2_sortStation/hw_5-2_sortStationMain.c +) + +# Связывание с библиотеками +target_link_libraries(hw_5_2_sortStation + PRIVATE + stackLib + hw_5_2_sortStationLib +) + +# Установка путей заголовочных файлов для sortingStation +target_include_directories(hw_5_2_sortStation + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/stack + ${CMAKE_CURRENT_SOURCE_DIR}/src/hw_5-2_sortStation +) + +# ======== Цель для сборки всех проектов ============ +add_custom_target(all_projects + DEPENDS + hw_5_1_proBrackets + hw_5_2_sortStation +) diff --git a/src/hw_5-1_proBrackets/CMakeLists.txt b/src/hw_5-1_proBrackets/CMakeLists.txt new file mode 100644 index 0000000..d9bc5e7 --- /dev/null +++ b/src/hw_5-1_proBrackets/CMakeLists.txt @@ -0,0 +1,8 @@ +# Создание статической библиотеки для модуля сортировочной станции +add_library(hw_5_1_proBracketsLib STATIC hw_5-1_proBrackets.c) + +# Установка путей для включения заголовочных файлов +target_include_directories(hw_5_1_proBracketsLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# Указание зависимости от библиотеки стека +target_link_libraries(hw_5_1_proBracketsLib PRIVATE stackLib) diff --git a/src/hw_5-1_proBrackets/hw_5-1_proBrackets.c b/src/hw_5-1_proBrackets/hw_5-1_proBrackets.c new file mode 100644 index 0000000..ca29c72 --- /dev/null +++ b/src/hw_5-1_proBrackets/hw_5-1_proBrackets.c @@ -0,0 +1,34 @@ +#include "hw_5-1_proBrackets.h" +#include "stack.h" +#include +#include + +int isValidBrackets(char originalString[]) +{ + Stack* bracketsStack = stackNew(); + + for (int i = 0; i < strlen(originalString); i++) { + char s = originalString[i]; + + if ((s == '(') || (s == '{') || (s == '[')) { + stackPush(bracketsStack, s); + + } else if ((s == ')' && bracketsStack == NULL) + || (s == '}' && bracketsStack == NULL) + || (s == ']' && bracketsStack == NULL)) { + return 0; + + } else if ((s == ')' && stackPeek(bracketsStack) == '(') + || (s == '}' && stackPeek(bracketsStack) == '{') + || (s == ']' && stackPeek(bracketsStack) == '[')) { + stackPop(bracketsStack); + + } else { + return 0; + } + } + if (bracketsStack != NULL && bracketsStack->top != NULL) { + return 0; + } + return 1; +} diff --git a/src/hw_5-1_proBrackets/hw_5-1_proBrackets.h b/src/hw_5-1_proBrackets/hw_5-1_proBrackets.h new file mode 100644 index 0000000..d03d442 --- /dev/null +++ b/src/hw_5-1_proBrackets/hw_5-1_proBrackets.h @@ -0,0 +1,10 @@ +#ifndef PROBRACKETS_H +#define PROBRACKETS_H + +// проверка корректности расстановки скобок +int isValidBrackets(char originalString[]); + +// ввод данных и вывод результата +int main(void); + +#endif \ No newline at end of file diff --git a/src/hw_5-1_proBrackets/hw_5-1_proBracketsMain.c b/src/hw_5-1_proBrackets/hw_5-1_proBracketsMain.c new file mode 100644 index 0000000..f3f0cdb --- /dev/null +++ b/src/hw_5-1_proBrackets/hw_5-1_proBracketsMain.c @@ -0,0 +1,18 @@ +#include "hw_5-1_proBrackets.h" +#include "stack.h" +#include +#include + +int main(void) +{ + char originalString[100]; + scanf("%99s", originalString); + int result = isValidBrackets(originalString); + + if (result == 0) { + printf("String doesn't follow rules.\n"); + return -1; + } + printf("Balance of brackets is keep.\n"); + return 0; +} diff --git a/src/hw_5-2_sortStation/CMakeLists.txt b/src/hw_5-2_sortStation/CMakeLists.txt new file mode 100644 index 0000000..ca0a9a5 --- /dev/null +++ b/src/hw_5-2_sortStation/CMakeLists.txt @@ -0,0 +1,8 @@ +# Создание статической библиотеки для модуля сортировочной станции +add_library(hw_5_2_sortStationLib STATIC hw_5-2_sortStation.c) + +# Установка путей для включения заголовочных файлов +target_include_directories(hw_5_2_sortStationLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# Указание зависимости от библиотеки стека +target_link_libraries(hw_5_2_sortStationLib PRIVATE stackLib) diff --git a/src/hw_5-2_sortStation/hw_5-2_sortStation.c b/src/hw_5-2_sortStation/hw_5-2_sortStation.c new file mode 100644 index 0000000..71cd745 --- /dev/null +++ b/src/hw_5-2_sortStation/hw_5-2_sortStation.c @@ -0,0 +1,78 @@ +#include "hw_5-2_sortStation.h" +#include "stack.h" +#include +#include +#include +#include + +// определение приоритета операторов +int precedence(char oper) +{ + if (oper == '+' || oper == '-') { + return 1; + } else if (oper == '*' || oper == '/') { + return 2; + } + return 0; +} + +// преобразование инфиксного выражения в постфиксное +void infixToPostfix(const char* infix, char* postfix) +{ + Stack* infixStack = stackNew(); // создаем стек для операторов + int j = 0; // индекс для записи в выходную строку + + // проходим по каждому символу входной строки + for (int i = 0; infix[i] != '\0'; i++) { + char current = infix[i]; + + // если пробел, пропускаем + if (current == ' ') { + continue; + } + + // если цифра, добавляем в выходную строку + if (isdigit(current)) { + postfix[j++] = current; + postfix[j++] = ' '; // добавляем пробел после числа + } + // если открывающая скобка, помещаем ее в стек + else if (current == '(') { + stackPush(infixStack, current); + } + // если закрывающая скобка.. + else if (current == ')') { + // извлекаем операторы из стека до открывающей скобки + while (infixStack != NULL && infixStack->top != NULL && stackPeek(infixStack) != '(') { + postfix[j++] = stackPop(infixStack); + postfix[j++] = ' '; + } + // удаляем открывающую скобку из стека + if (infixStack != NULL && infixStack->top != NULL && stackPeek(infixStack) == '(') { + stackPop(infixStack); + } + } + // если оператор (+, -, *, /).. + else if (current == '+' || current == '-' || current == '*' || current == '/') { + // извлекаем операторы с более высоким или равным приоритетом + while ((infixStack != NULL && infixStack->top != NULL) && precedence(stackPeek(infixStack)) >= precedence(current)) { + postfix[j++] = stackPop(infixStack); + postfix[j++] = ' '; + } + // помещаем текущий оператор в стек + stackPush(infixStack, current); + } + } + + // извлекаем все оставшиеся операторы из стека + while (infixStack != NULL && infixStack->top != NULL) { + postfix[j++] = stackPop(infixStack); + postfix[j++] = ' '; + } + + // завершаем строку + postfix[j] = '\0'; + + // удаляем стек + stackDelete(infixStack); +} diff --git a/src/hw_5-2_sortStation/hw_5-2_sortStation.h b/src/hw_5-2_sortStation/hw_5-2_sortStation.h new file mode 100644 index 0000000..99daf53 --- /dev/null +++ b/src/hw_5-2_sortStation/hw_5-2_sortStation.h @@ -0,0 +1,13 @@ +#ifndef SORTSTATION_H +#define SORTSTATION_H + +// преобразование инфиксного выражения в постфиксное +void infixToPostfix(const char* infix, char* postfix); + +// проверка приоритета операторов +int precedence(char op); + +// ввод данных и вывод результата +int main(void); + +#endif \ No newline at end of file diff --git a/src/hw_5-2_sortStation/hw_5-2_sortStationMain.c b/src/hw_5-2_sortStation/hw_5-2_sortStationMain.c new file mode 100644 index 0000000..9ebfcbc --- /dev/null +++ b/src/hw_5-2_sortStation/hw_5-2_sortStationMain.c @@ -0,0 +1,25 @@ +#include "hw_5-2_sortStation.h" +#include "stack.h" +#include +#include +#include +#include + +int main() +{ + char infix[100]; + char postfix[100]; + + printf("Введите инфиксное выражение (например, (1 + 1) * 2): "); + fgets(infix, sizeof(infix), stdin); + + // удаляем символ новой строки, если он есть + infix[strcspn(infix, "\n")] = 0; + + // преобразуем в постфиксную запись + infixToPostfix(infix, postfix); + + printf("Постфиксная запись: %s\n", postfix); + + return 0; +} diff --git a/src/stack/CMakeLists.txt b/src/stack/CMakeLists.txt new file mode 100644 index 0000000..83e9310 --- /dev/null +++ b/src/stack/CMakeLists.txt @@ -0,0 +1,5 @@ +# Создание статической библиотеки для модуля стека +add_library(stackLib STATIC stack.c) + +# Установка путей для включения заголовочных файлов +target_include_directories(stackLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/stack/stack.c b/src/stack/stack.c new file mode 100644 index 0000000..f764cc2 --- /dev/null +++ b/src/stack/stack.c @@ -0,0 +1,86 @@ +#include "stack.h" +#include +#include + +// создание пустого стека +Stack* stackNew(void) +{ + Stack* stack = (Stack*)malloc(sizeof(Stack)); + if (stack != NULL) { + stack->top = NULL; + } + return stack; +} + +// добавление элемента на стек +int stackPush(Stack* stack, int value) +{ + if (stack == NULL) { + printf("Stack is NULL!\n"); + return -1; + } + + // создаем новый узел + Node* new_node = (Node*)malloc(sizeof(Node)); + if (new_node == NULL) { + printf("Memory failed!\n"); + return -1; + } + + // заполняем узел + new_node->data = value; + new_node->next = stack->top; + + // обновляем вершину стека + stack->top = new_node; +} + +// взятие элемента со стека +int stackPop(Stack* stack) +{ + if (stack == NULL || stack->top == NULL) { + printf("Stack is empty!\n"); + return -1; + } + + // сохраняем данные из вершины + Node* temp = stack->top; + int value = temp->data; + + // перемещаем вершину на следующий элемент + stack->top = stack->top->next; + + // освобождаем память удаляемого узла + free(temp); + + return value; +} + +// просмотр элемента на вершине стека +int stackPeek(Stack* stack) +{ + if (stack == NULL || stack->top == NULL) { + printf("Stack is empty!\n"); + return -1; + } + + return stack->top->data; +} + +// удаление всего стека и освобождение памяти +void stackDelete(Stack* stack) +{ + if (stack == NULL) { + return; + } + + // освобождаем все узлы + while (stack->top != NULL) { + Node* temp = stack->top; + stack->top = stack->top->next; + free(temp); + } + + // освобождаем саму структуру стека + free(stack); +} \ No newline at end of file diff --git a/src/stack/stack.h b/src/stack/stack.h new file mode 100644 index 0000000..4dde183 --- /dev/null +++ b/src/stack/stack.h @@ -0,0 +1,29 @@ +#ifndef STACK_H +#define STACK_H + +#include + +// максимальный размер стека +#define STACK_MAX_SIZE 100 + +// структура узла стека +typedef struct Node { + int data; // целочисленные данные + struct Node* next; // указатель на следующий узел +} Node; + +// структура стека +typedef struct { + Node* top; // указатель на вершину стека +} Stack; + +// основные операции +int stackPush(Stack* stack, int value); // положить элемент на стек +int stackPop(Stack* stack); // взять элемент со стека +int stackPeek(Stack* stack); // посмотреть на элемент на вершине стека + +// служебные функции +Stack* stackNew(void); // создать пустой стек +void stackDelete(Stack* stack); // удалить весь стек (освободить память) + +#endif \ No newline at end of file