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..1ab107d --- /dev/null +++ b/src/hw_5-2_sortStation/hw_5-2_sortStation.c @@ -0,0 +1,97 @@ +#include "hw_5-2_sortStation/hw_5-2_sortStation.h" +#include "stack/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); +} + +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/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/instruction.md b/src/hw_5-2_sortStation/instruction.md new file mode 100644 index 0000000..95c6f50 --- /dev/null +++ b/src/hw_5-2_sortStation/instruction.md @@ -0,0 +1,17 @@ +# Инструкция по сборке + +Домашнее задание 5.2 Сортировочная станция + +1. Откройте терминал и перейдите в директорию с файлами приложения (hw_5-2_sortStation) +2. Выполните команду компиляции: +```console +gcc hw_5-2_sortStation.c ../stack/stack.c -I.. -o hw_5-2_sortStation +``` +3. Запустите программу: +```console +./hw_5-2_sortStation +``` +### Использование +1. Введите строку с математическим выражением в инфиксной форме (не более 100 чисел) +2. Нажмите Enter для завершения ввода +3. Программа выведет математическое выражение в постфиксной форме \ No newline at end of file diff --git a/src/stack/stack.c b/src/stack/stack.c new file mode 100644 index 0000000..caec476 --- /dev/null +++ b/src/stack/stack.c @@ -0,0 +1,81 @@ +#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..7951dc1 --- /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