Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions semester_1/homework5/sortingStation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
107 changes: 107 additions & 0 deletions semester_1/homework5/sortingStation/Stack/Stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include <stdlib.h>

#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;
}

char *createString(Stack const *const stack, StackErrorCode *const errorCode)
{
if (stack == NULL || stack->head == NULL)
{
*errorCode = emptyStack;
return NULL;
}

size_t strl = stack->length * 2;
char *output = (char *)malloc(strl * sizeof(char));
if (output == NULL)
{
*errorCode = memoryErrorStack;
return NULL;
}

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;
}
27 changes: 27 additions & 0 deletions semester_1/homework5/sortingStation/Stack/Stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#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 * const errorCode);
37 changes: 37 additions & 0 deletions semester_1/homework5/sortingStation/getString/getString.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "getString.h"

char *getString(FILE const * const 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;
}
8 changes: 8 additions & 0 deletions semester_1/homework5/sortingStation/getString/getString.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <stdbool.h>
#include <string.h>
#include <stdio.h>

// получить строку из *file до разделителя endOfLine
char *getString(FILE const * const file, char const endOfLine);
47 changes: 47 additions & 0 deletions semester_1/homework5/sortingStation/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>

#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);
free(expression);
if (ex == NULL)
{
printf("\nНедостаточно памяти\n");
return memoryError;
}

printf("%s\n", ex);
free(ex);
return programFinishedCorrectly;
}
119 changes: 119 additions & 0 deletions semester_1/homework5/sortingStation/sortingStation/sortingStation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#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);
int comparison = compareOperators(top, currentChar);
while (ec != emptyStack && top != '(' && comparison != -1)
{
char operatorFromStack = getElement(operatorsStack, &ec);
ec = addElement(outputStack, operatorFromStack);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

проверить код ошибки

if (ec != okStack)
{
deleteStack(&operatorsStack);
deleteStack(&outputStack);
return NULL;
}
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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

удалить оба стека

deleteStack(&operatorsStack);
deleteStack(&outputStack);
return output;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

// получает на вход арифметическое выражение в инфиксной форме, возвращает то же выражение в постфиксной форме
char *createPostfixForm(char const *const infixForm);
Loading