diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8616e4f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.25) +project(homeworks C) + +add_compile_options(-Wall -Wextra -pedantic) + +add_subdirectory(src/stack) \ No newline at end of file diff --git a/src/stack/CMakeLists.txt b/src/stack/CMakeLists.txt new file mode 100644 index 0000000..18d415a --- /dev/null +++ b/src/stack/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(stack stack.c) + +add_executable(task2 task2.c) + +target_link_libraries(task2 PRIVATE stack) diff --git a/src/stack/instruction.txt b/src/stack/instruction.txt new file mode 100644 index 0000000..bb218c5 --- /dev/null +++ b/src/stack/instruction.txt @@ -0,0 +1,9 @@ +Task1: +gcc -Wall -Wextra -pedantic -c stack.c +gcc -Wall -Wextra -pedantic -c task1.c +gcc -Wall -Wextra -pedantic stack.o task1.o -o steakTask1 + +Task2: +gcc -Wall -Wextra -pedantic -c stack.c +gcc -Wall -Wextra -pedantic -c task2.c +gcc -Wall -Wextra -pedantic stack.o task2.o -o steakTask2 \ No newline at end of file diff --git a/src/stack/stack.c b/src/stack/stack.c new file mode 100644 index 0000000..4674854 --- /dev/null +++ b/src/stack/stack.c @@ -0,0 +1,54 @@ +#include "stack.h" +#include +#include + +struct StackNode { + int value; + struct StackNode* next; +}; + +struct Stack { + struct StackNode* head; +}; + +Stack* newStack() +{ + Stack* stack = (Stack*)malloc(sizeof(Stack)); + if (!stack) + return NULL; + stack->head = NULL; + return stack; +} + +void push(struct Stack* stack, int value) +{ + struct StackNode* node = (struct StackNode*)malloc(sizeof(struct StackNode)); + + node->value = value; + node->next = stack->head; + stack->head = node; +} + +int pop(Stack* stack) +{ + struct StackNode* oldNode = stack->head; + int res = oldNode->value; + + stack->head = oldNode->next; + free(oldNode); + + return res; +} + +int isEmpty(Stack* stack) +{ + return stack->head == NULL; +} + +void deleteStack(Stack* stack) +{ + while (!isEmpty(stack)) { + pop(stack); + } + 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..cf0314a --- /dev/null +++ b/src/stack/stack.h @@ -0,0 +1,9 @@ +#pragma once + +typedef struct Stack Stack; + +Stack* newStack(); // Создание стека. +void push(Stack* stack, int value); // Добавляет элемент на вершину стека. +int pop(Stack* stack); // Убирает из стека элемент и возвращает его. Необходимо проверять isEmpty перед вызовом +int isEmpty(Stack* stack); +void deleteStack(Stack* stack); // Удаление стека. \ No newline at end of file diff --git a/src/stack/task2.c b/src/stack/task2.c new file mode 100644 index 0000000..8acb6f8 --- /dev/null +++ b/src/stack/task2.c @@ -0,0 +1,105 @@ +#include "stack.h" +#include +#include + +int precedence(char op) +{ + if (op == '*' || op == '/') + return 2; + if (op == '+' || op == '-') + return 1; + return 0; +} + +int isOperator(char c) +{ + return c == '+' || c == '-' || c == '*' || c == '/'; +} + +int isDigit(char c) +{ + return c >= '0' && c <= '9'; +} + +/* +Пользователь должен выделить минимум 2 * strlen(infix) символ. +return 1 — если преобразование прошло успешно, +return 0 — если ошибка (неправильные скобки или неподдерживаемый символ). +*/ +int infixToPostfix(char* infix, char* postfix) +{ + Stack* st = newStack(); + int rpn = 0; // индекс для записи в reverse polish notation(постфиксная запись) + + for (int i = 0; infix[i]; ++i) { + char c = infix[i]; + + if (isDigit(c)) { + postfix[rpn++] = c; + } else if (c == '(') { + push(st, c); + } else if (c == ')') { + int found = 0; + while (!isEmpty(st)) { + int top = pop(st); + if (top == '(') { + found = 1; + break; + } + postfix[rpn++] = (char)top; + } + + if (!found) { + printf("лишняя закрывающая скобка ')'\n"); + deleteStack(st); + return 0; + } + } else if (isOperator(c)) { + while (!isEmpty(st)) { + int top = pop(st); + if (precedence(top) < precedence(c)) { + push(st, top); + break; + } + postfix[rpn++] = (char)top; + } + push(st, c); + } else { + printf("неподдерживаемый символ '%c'\n", c); + deleteStack(st); + return 0; + } + } + + // проверка не осталось ли незакрытых скобок + while (!isEmpty(st)) { + int top = pop(st); + if (top == '(') { + printf("лишняя открывающая скобка '('\n"); + deleteStack(st); + return 0; + } + postfix[rpn++] = (char)top; + } + + postfix[rpn] = '\0'; + deleteStack(st); + return 1; +} + +int main(void) +{ + char input[100]; + char output[2 * 100]; + + printf("инфиксное выражение:\n"); + scanf("%99s", input); + + if (!infixToPostfix(input, output)) { + printf("ошибка.\n"); + return 1; + } + printf("постфиксное выражение: %s\n", output); + + return 0; +} \ No newline at end of file