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
130 changes: 130 additions & 0 deletions HW4/ShuntingYard/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "../../modules/queue/queue.h"
#include "../../modules/stack/stack.h"
#include <ctype.h>
#include <stdio.h>

void shuntingYard(const char *expression);
int getPrecedence(char operation);

int main() {
shuntingYard("1 + 1");
shuntingYard("(1 + 1) * 2");
shuntingYard("1 + 1 * 2");
shuntingYard("3 + 4 * 2 / (1 - 5)");
shuntingYard("1 + 2 + (3 + 4)");
return 0;
}

void shuntingYard(const char *expression) {
Stack *stackHead = NULL;
Queue *queueHead = NULL;
Queue *queueTail = NULL;
int errorCode = 0;

for (int i = 0; expression[i] != '\0'; ++i) {
char currChar = expression[i];

if (isdigit(currChar)) {
errorCode = pushToQueue(currChar, &queueHead, &queueTail);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
} else if (currChar == '+' || currChar == '-' || currChar == '*' ||
currChar == '/') {
while (stackHead != NULL &&
getPrecedence(currChar) <= getPrecedence(stackHead->data)) {
char lastStackOp = popFromStack(&stackHead);
if (lastStackOp == '\0') {
printf("Error: trying to put empty operation into queue\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
}
errorCode = pushToStack(currChar, &stackHead);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
} else if (currChar == '(') {
errorCode = pushToStack(currChar, &stackHead);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
} else if (currChar == ')') {
while (stackHead != NULL && stackHead->data != '(') {
char lastStackOp = popFromStack(&stackHead);
if (lastStackOp == '\0') {
printf("Error: trying to put empty operation into queue\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
}
if (popFromStack(&stackHead) != '(') {
printf("Error: mismatched parentheses\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
} else if (currChar != ' ') {
printf("Error: wrong math expression\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
}
while (stackHead != NULL) {
char lastStackOp = popFromStack(&stackHead);
if (lastStackOp == '\0') {
printf("Error: trying to put empty operation into queue\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail);
if (errorCode == -1) {
printf("Error: couldn't allocate memory\n");
freeQueue(queueHead);
freeStack(stackHead);
return;
}
}

printQueue(queueHead);
freeQueue(queueHead);
freeStack(stackHead);
return;
}

int getPrecedence(char operation) {
if (operation == '/' || operation == '*')
return 1;
else if (operation == '-' || operation == '+')
return 0;
else
return -1;
}

39 changes: 39 additions & 0 deletions HW4/modules/queue/queue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>

int pushToQueue(char data, Queue **head, Queue **tail) {
Queue *newQueueNode = (Queue *)malloc(sizeof(Queue));
if (newQueueNode == NULL)
return -1;

newQueueNode->data = data;
newQueueNode->next = NULL;

if (*head == NULL) {
*head = newQueueNode;
*tail = newQueueNode;
} else {
(*tail)->next = newQueueNode;
*tail = newQueueNode;
}
return 0;
}

void printQueue(Queue *head) {
while (head != NULL) {
printf("%c ", head->data);
head = head->next;
}
printf("\n");
}

void freeQueue(Queue *head) {
Queue *current = head;
while (current != NULL) {
Queue *next = current->next;
free(current);
current = next;
}
}

28 changes: 28 additions & 0 deletions HW4/modules/queue/queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

typedef struct Queue {
char data;
struct Queue *next;
} Queue;

/**
* @brief Push element to queue
* @param data Character to push
* @param head Pointer to pointer of queue head
* @param tail Pointer to pointer of queue tail
* @return -1 if couldn't allocate memory, 0 otherwise
*/
int pushToQueue(char data, Queue **head, Queue **tail);

/**
* @brief Print all elements in queue
* @param head Pointer to queue head
*/
void printQueue(Queue *head);

/**
* @brief Free all queue memory
* @param head Pointer to queue head
*/
void freeQueue(Queue *head);

37 changes: 37 additions & 0 deletions HW4/modules/stack/stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "stack.h"
#include <stdlib.h>
#include <stdio.h>

int pushToStack(char data, Stack **head) {
Stack *newNode =
(Stack *)malloc(sizeof(Stack));
if (newNode == NULL)
return -1;
else {
newNode->data = data;
newNode->next = *head;
*head = newNode;
return 0;
}
}

char popFromStack(Stack **head) {
if (*head == NULL)
return '\0';

Stack *lastNode = *head;
char lastNodeData = lastNode->data;
*head = (*head)->next;
free(lastNode);
return lastNodeData;
}

void freeStack(Stack *head) {
Stack *current = head;
while (current != NULL) {
Stack *next = current->next;
free(current);
current = next;
}
}

28 changes: 28 additions & 0 deletions HW4/modules/stack/stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

typedef struct Stack {
char data;
struct Stack *next;
} Stack;

/**
* @brief Push element to stack
* @param data Character to push
* @param head Pointer to pointer of stack head
* @return -1 if couldn't allocate memory, 0 otherwise
*/
int pushToStack(char data, Stack **head);

/**
* @brief Pop element from stack
* @param head Pointer to pointer of stack head
* @return Popped character or '\0' if stack is empty
*/
char popFromStack(Stack **head);

/**
* @brief Free all stack memory
* @param head Pointer to stack head
*/
void freeStack(Stack *head);