usaa24/sk2/calculator.c

129 lines
4.2 KiB
C
Raw Normal View History

2025-01-31 18:14:04 +00:00
#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
// Overenie, či je znak operátor
bool je_operator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Určenie priority operátorov
int priorita(char op) {
switch (op) {
case '+': case '-': return 1;
case '*': case '/': return 2;
case '^': return 3;
default: return 0;
}
}
// Matematické operácie
double scitaj(double a, double b) { return a + b; }
double odcitaj(double a, double b) { return a - b; }
double nasob(double a, double b) { return a * b; }
double del(double a, double b) { return a / b; }
2025-01-31 21:05:10 +00:00
double sinus(double x) { return sin(x); }
double cosinus(double x) { return cos(x); }
double odmocnin(double x) { return sqrt(x); }
2025-01-31 21:14:34 +00:00
double mocnina(double zaklad, double exponent) { return pow(zaklad, exponent); }
2025-01-31 21:05:10 +00:00
double logaritmus(double x) { return log(x); }
2025-01-31 18:14:04 +00:00
// Funkcia na konverziu infixového výrazu na postfixový (Shunting-yard algoritmus)
2025-01-31 21:14:34 +00:00
void infix_na_postfix(const char *infix, char **postfix) {
int capacity = 100; // Počiatočná kapacita
*postfix = malloc(capacity * sizeof(char));
char *stack = malloc(capacity * sizeof(char));
2025-01-31 18:14:04 +00:00
int top = -1;
int j = 0;
2025-01-31 21:14:34 +00:00
2025-01-31 18:14:04 +00:00
for (int i = 0; infix[i] != '\0'; i++) {
2025-01-31 21:14:34 +00:00
// Ak je znak číslo alebo desatinná bodka, pridaj do postfix
2025-01-31 18:14:04 +00:00
if (isdigit(infix[i]) || infix[i] == '.') {
2025-01-31 21:14:34 +00:00
// Ak je číslo, spracuj celé číslo
while (isdigit(infix[i]) || infix[i] == '.') {
(*postfix)[j++] = infix[i++];
if (j >= capacity) {
capacity *= 2;
*postfix = realloc(*postfix, capacity * sizeof(char));
}
}
i--; // Zníž i, pretože cyklus už inkrementoval i
(*postfix)[j++] = ' '; // Oddelenie čísel
}
// Ak je operátor
else if (je_operator(infix[i])) {
(*postfix)[j++] = ' ';
2025-01-31 18:14:04 +00:00
while (top != -1 && priorita(stack[top]) >= priorita(infix[i])) {
2025-01-31 21:14:34 +00:00
(*postfix)[j++] = stack[top--];
(*postfix)[j++] = ' ';
2025-01-31 18:14:04 +00:00
}
stack[++top] = infix[i];
2025-01-31 21:14:34 +00:00
}
// Ak je otvorená zátvorka
else if (infix[i] == '(') {
2025-01-31 18:14:04 +00:00
stack[++top] = infix[i];
2025-01-31 21:14:34 +00:00
}
// Ak je zatvorená zátvorka
else if (infix[i] == ')') {
2025-01-31 18:14:04 +00:00
while (top != -1 && stack[top] != '(') {
2025-01-31 21:14:34 +00:00
(*postfix)[j++] = ' ';
(*postfix)[j++] = stack[top--];
2025-01-31 18:14:04 +00:00
}
2025-01-31 21:14:34 +00:00
top--; // Odstrániť '(' zo zásobníka
2025-01-31 18:14:04 +00:00
}
}
2025-01-31 21:14:34 +00:00
// Vyprázdni zásobník
2025-01-31 18:14:04 +00:00
while (top != -1) {
2025-01-31 21:14:34 +00:00
(*postfix)[j++] = ' ';
(*postfix)[j++] = stack[top--];
2025-01-31 18:14:04 +00:00
}
2025-01-31 21:14:34 +00:00
(*postfix)[j] = '\0';
free(stack);
2025-01-31 18:14:04 +00:00
}
// Vyhodnotenie postfixového výrazu
double vyhodnot_postfix(const char *postfix) {
2025-01-31 21:14:34 +00:00
int capacity = 100;
double *stack = malloc(capacity * sizeof(double));
2025-01-31 18:14:04 +00:00
int top = -1;
2025-01-31 18:20:13 +00:00
char *postfix_copy = malloc(strlen(postfix) + 1);
strcpy(postfix_copy, postfix);
char *token = strtok(postfix_copy, " ");
2025-01-31 18:14:04 +00:00
while (token) {
2025-01-31 21:14:34 +00:00
// Ak je token číslo, pridaj na zásobník
2025-01-31 18:14:04 +00:00
if (isdigit(token[0]) || (token[0] == '-' && isdigit(token[1]))) {
stack[++top] = atof(token);
2025-01-31 21:14:34 +00:00
}
// Ak je operátor, vykonaj operáciu
else if (je_operator(token[0]) && token[1] == '\0') {
2025-01-31 18:14:04 +00:00
double b = stack[top--];
double a = stack[top--];
switch (token[0]) {
case '+': stack[++top] = scitaj(a, b); break;
case '-': stack[++top] = odcitaj(a, b); break;
case '*': stack[++top] = nasob(a, b); break;
2025-01-31 21:14:34 +00:00
case '/':
if (b == 0) {
printf("Chyba: delenie nulou!\n");
free(stack);
free(postfix_copy);
exit(1);
}
stack[++top] = del(a, b);
break;
2025-01-31 18:14:04 +00:00
case '^': stack[++top] = mocnina(a, b); break;
}
}
token = strtok(NULL, " ");
}
2025-01-31 21:14:34 +00:00
double result = stack[top];
free(stack);
2025-01-31 18:20:13 +00:00
free(postfix_copy);
2025-01-31 21:14:34 +00:00
return result;
2025-01-31 18:14:04 +00:00
}