Conversation
shknoko
commented
Oct 23, 2025
- Stack implementation
- Fixed bug in StackNode definition
- Brackets checker
- Added peek function in stack
- Shunting yard algorithm
|
|
||
| void push(Stack* stack, char data) | ||
| { | ||
| StackNode* element = (StackNode*)calloc(1, sizeof(StackNode)); |
There was a problem hiding this comment.
Nit: конечно, calloc() может не сработать, это лучше бы учитывать и проверять, что вызов вернул не NULL.
| if (isEmpty(stack)) { | ||
| return '\0'; | ||
| } | ||
|
|
||
| StackNode* oldNode = stack->head; | ||
| char data = oldNode->data; | ||
| stack->head = stack->head->next; |
There was a problem hiding this comment.
Minor: нетривиальные предположения лучше помещать в assert()
| if (isEmpty(stack)) { | |
| return '\0'; | |
| } | |
| StackNode* oldNode = stack->head; | |
| char data = oldNode->data; | |
| stack->head = stack->head->next; | |
| if (isEmpty(stack)) { | |
| return '\0'; | |
| } | |
| assert(stack->head != NULL); | |
| StackNode* oldNode = stack->head; | |
| char data = oldNode->data; | |
| stack->head = stack->head->next; |
| void deleteStack(Stack* stack) | ||
| { | ||
| while (!isEmpty(stack)) { | ||
| pop(stack); | ||
| } | ||
| free(stack); | ||
| } |
There was a problem hiding this comment.
Nit: обычно функции удаления хорошо делать устойчивыми к NULL входам.
| void deleteStack(Stack* stack) | |
| { | |
| while (!isEmpty(stack)) { | |
| pop(stack); | |
| } | |
| free(stack); | |
| } | |
| void deleteStack(Stack* stack) | |
| { | |
| if (stack == NULL) return; | |
| while (!isEmpty(stack)) { | |
| pop(stack); | |
| } | |
| free(stack); | |
| } |
| } | ||
| *res = *res && isEmpty(stack); | ||
| deleteStack(stack); | ||
| return 0; |
There was a problem hiding this comment.
Nit: немного странно, что получить не 0 нельзя. Хотя функция может привести к UB (например, если память закончилась).
| if ((str[i] == '(') || (str[i] == '[') || (str[i] == '{')) { | ||
| push(stack, str[i]); | ||
| } else if ((str[i] == ')') || (str[i] == ']') || (str[i] == '}')) { | ||
| if (!isEmpty(stack)) { | ||
| char popped = pop(stack); | ||
| if (((str[i] == ')') && (popped != '(')) || ((str[i] == ']') && (popped != '[')) || ((str[i] == '}') && (popped != '{'))) { | ||
| *res = false; | ||
| } | ||
| } else { | ||
| *res = false; | ||
| } | ||
| } |
There was a problem hiding this comment.
Minor: Я бы попробовал тут switch, но, вообще говоря, код в любом случае будто бы немного дублируется. Так что просто вкусовщина.
| fgets(input, n + 1, stdin); | ||
|
|
||
| bool res = true; | ||
| bracketsChecker(input, &res); |
There was a problem hiding this comment.
Nit: а тут return code не проверяется.
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
| int getPriority(char operation) |
There was a problem hiding this comment.
Nit: обычно precedence вместо priority
| { | ||
| unsigned lastUsedResIndex = 0; | ||
| Stack* stack = newStack(); | ||
| unsigned long len = strlen(str); |
There was a problem hiding this comment.
Minor:
| unsigned long len = strlen(str); | |
| size_t len = strlen(str); |
Ну это совсем придирка, просто strlen() отдает size_t, наверняка есть платформы, где unsigned long будет 32 бита, а size_t --- 64.
| while (i < len && isdigit(str[i])) { | ||
| res[lastUsedResIndex] = str[i]; | ||
| lastUsedResIndex++; | ||
| i++; | ||
| } | ||
| if (i < len) { | ||
| i--; | ||
| } |
There was a problem hiding this comment.
Есть у меня некоторые подозрения, что можно было написать вот так:
| while (i < len && isdigit(str[i])) { | |
| res[lastUsedResIndex] = str[i]; | |
| lastUsedResIndex++; | |
| i++; | |
| } | |
| if (i < len) { | |
| i--; | |
| } | |
| res[lastUsedResIndex] = str[i]; | |
| lastUsedResIndex++; |
И поведение было бы такое же. Ну в смысле -- нет необходимости во вложенном цикле. Но это так -- с первого взгляда.
А то с этим сдвигом влево не совсем понятно выходит, что происходит.
| if (isEmpty(stack)) { | ||
| deleteStack(stack); | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
Minor: одно из немногих мест, когда я бы рассмотрел goto. Так легче "не забыть почистить память". Ну и строк меньше.
if (isEmpty(stack)) goto error;
// ...
error:
deleteStack(stack);
return 1;А вот в Go это бы сделал defer :)