diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt new file mode 100644 index 0000000..b1aeae0 --- /dev/null +++ b/CMake/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.10) +project(StackLibrary C) + +set(CMAKE_C_STANDARD 11) + +add_library(mylib STATIC + sorting_station.c + advanced_braces_balance.c + Stack/stack.c +) + +if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options(/W4) +endif() + +target_include_directories(mylib PUBLIC . Stack) diff --git a/CMake/Stack/stack.c b/CMake/Stack/stack.c new file mode 100644 index 0000000..108392a --- /dev/null +++ b/CMake/Stack/stack.c @@ -0,0 +1,54 @@ +#include "stack.h" + +#include +#include + +Stack* stackNew() { + Stack* stack = malloc(sizeof(Stack)); + if (stack == NULL) { + puts("Memory allocation error"); + return NULL; + } + stack -> previous = NULL; + stack -> value = NULL; + return stack; +} + +void stackPush(Stack** stack, void* value) { + if (stack == NULL || *stack == NULL) { + puts("Incorrect arguments error"); + return; + } + Stack* stackTop = malloc(sizeof(Stack)); + if (stackTop == NULL) { + puts("Memory allocation error"); + return; + } + stackTop -> value = value; + stackTop -> previous = *stack; + *stack = stackTop; +} + +void stackPop(Stack** stack) { + if (stack == NULL || *stack == NULL) { + puts("Incorrect arguments error"); + return; + } + Stack* stackTop = (*stack) -> previous; + if (stackTop != NULL) { + free(*stack); + *stack = stackTop; + } +} + +void stackFree(Stack** stack) { + if (stack == NULL || *stack == NULL) { + puts("Incorrect arguments error"); + return; + } + while ((*stack)->previous != NULL) { + stackPop(stack); + } + free(*stack); + *stack = NULL; +} diff --git a/CMake/Stack/stack.h b/CMake/Stack/stack.h new file mode 100644 index 0000000..b00d9d3 --- /dev/null +++ b/CMake/Stack/stack.h @@ -0,0 +1,20 @@ +#pragma once + +// The StackStruct structure with the value and previous fields +// Defined as Stack +typedef struct StackStruct { + void * value; + struct StackStruct *previous; +} Stack; + +// Create a new stack +Stack* stackNew(); + +// Add a new element to the top of the stack +void stackPush(Stack**, void*); + +// Remove an element from the top of the stack +void stackPop(Stack**); + +// Free the stack +void stackFree(Stack**); \ No newline at end of file diff --git a/CMake/advanced_braces_balance.c b/CMake/advanced_braces_balance.c new file mode 100644 index 0000000..a6baaa6 --- /dev/null +++ b/CMake/advanced_braces_balance.c @@ -0,0 +1,49 @@ +#include "advanced_braces_balance.h" + +bool checkBalance(char* string) { + Stack* stack = stackNew(); + if (stack == NULL) { + return false; + } + + for (int index = 0; index < strlen(string); ++index) { + const char character = string[index]; + + if (character == '{' || character == '[' || character == '(') { + char* value = malloc(sizeof(char)); + if (value == NULL) { + puts("Memory allocation error"); + stackFree(&stack); + return false; + } + *value = character; + stackPush(&stack, value); + } + + else if (character == '}' || character == ']' || character == ')') { + if (stack -> value == NULL) { + stackFree(&stack); + return false; + } + + char* topValue = (char*) stack -> value; + char topChar = (char)*topValue; + + if ((character == '}' && topChar != '{') || + (character == ']' && topChar != '[') || + (character == ')' && topChar != '(')) { + stackFree(&stack); + return false; + } + + free(stack->value); + stackPop(&stack); + } + } + + bool balanced = (stack->value == NULL); + + stackFree(&stack); + + return balanced; +} \ No newline at end of file diff --git a/CMake/advanced_braces_balance.h b/CMake/advanced_braces_balance.h new file mode 100644 index 0000000..fcdc7f0 --- /dev/null +++ b/CMake/advanced_braces_balance.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Stack/stack.h" + +#include +#include +#include +#include + +bool checkBalance(char* string); diff --git a/CMake/sorting_station.c b/CMake/sorting_station.c new file mode 100644 index 0000000..66e5bc6 --- /dev/null +++ b/CMake/sorting_station.c @@ -0,0 +1,58 @@ +#include "sorting_station.h" + +int getPriority(char operation) { + return (operation == '+' || operation == '-') ? 1 : (operation == '*' || operation == '/') ? 2 : 0; +} + +char* sortingStationAlgorithm(char* expression) { + expression = strdup(expression); + + Stack* stack = stackNew(); + + char* token = strtok(expression, " "); + + char* result = malloc(strlen(expression) * 2); + result[0] = '\0'; + + while (token != NULL) { + if (isdigit(token[0])) { + strcat(result, token); + strcat(result, " "); + } + else if (token[0] == '(') { + stackPush(&stack, strdup(token)); + } + else if (token[0] == ')') { + while (stack != NULL && stack -> value != NULL && + ((char*) stack -> value)[0] != '(') { + strcat(result, (char*) stack -> value); + strcat(result, " "); + stackPop(&stack); + } + if (stack && stack -> value) { + stackPop(&stack); + } + } + else if (token[0] == '*' || token[0] == '/' || token[0] == '+' || token[0] == '-') { + while (stack != NULL && stack -> value != NULL && + getPriority(((char*) stack -> value)[0]) >= getPriority(token[0])) { + strcat(result, (char*) stack -> value); + strcat(result, " "); + stackPop(&stack); + } + stackPush(&stack, strdup(token)); + } + token = strtok(NULL, " "); + } + + while (stack != NULL && stack -> value != NULL) { + strcat(result, (char*) stack -> value); + strcat(result, " "); + stackPop(&stack); + } + + free(expression); + stackFree(&stack); + + return result; +} \ No newline at end of file diff --git a/CMake/sorting_station.h b/CMake/sorting_station.h new file mode 100644 index 0000000..dcb2514 --- /dev/null +++ b/CMake/sorting_station.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Stack/stack.h" +#include +#include +#include +#include + +int getPriority(char); + +char* sortingStationAlgorithm(char*);