diff --git a/sk2/Makefile b/sk2/Makefile index e69de29..a433323 100644 --- a/sk2/Makefile +++ b/sk2/Makefile @@ -0,0 +1,17 @@ +CC=gcc +CFLAGS=-Wall -Wextra -std=c11 +OBJ=main.o calculator.o + +all: calculator + +kalkulacka: $(OBJ) + $(CC) $(CFLAGS) -o calculator $(OBJ) -lm + +main.o: main.c calculator.h + $(CC) $(CFLAGS) -c main.c + +calculator.o: calculator.c calculator.h + $(CC) $(CFLAGS) -c calculator.c + +clean: + rm -f calculator $(OBJ) diff --git a/sk2/README.md b/sk2/README.md index e69de29..88efe40 100644 --- a/sk2/README.md +++ b/sk2/README.md @@ -0,0 +1,46 @@ +Zadanie + + Naprogramuj vedeckú kalkulačku, ktorá bude vyhodnocovať aj zložitejšie výrazy v infixnej notácii. + + Kalkulačka by mala podporovať tieto operácie: + + Načítanie a prácu s číslami s presnosťou min. 2 desatinné miesta. + + Sčítanie, odčítanie, násobenie, delenie, zátvorky. + + Sinus, cosinus, odmocnina, druhá mocnina, logaritmus. + +Príklad použitia: + + (2 + 3) * 2 + 10 + (10 * 2) + (6 / 2) + 23 + +Opis funkčnosti + + Program vykonáva vyhodnotenie matematických výrazov zapísaných v infixnej notácii. Pre tento účel prevádza infixovú notáciu na postfixovú a následne vyhodnocuje výraz pomocou algoritmu "zásobníkovej" kalkulačky. + + Podporované operácie zahŕňajú aritmetické operácie (+, -, *, /) a vedecké funkcie ako sinus, cosinus, odmocnina, druhá mocnina a logaritmus. + +Opis riešenia + + Infixový výraz je najprv konvertovaný na postfixovú notáciu. + + Postfixový výraz je vyhodnotený pomocou zásobníka. + + Matematické operácie sú implementované samostatne pre zabezpečenie presnosti. + +Podmienky spustenia + + Program beží v prostredí s podporou jazyka C a knižnice math.h. + + Na kompiláciu je potrebné použiť príkaz make. + + Spustenie programu sa vykoná príkazom ./kalkulacka. + +Zoznam použitých zdrojov + + Dokumentácia k infixovej a postfixovej notácii: https://en.wikipedia.org/wiki/Shunting-yard_algorithm + + Dokumentácia k vedeckým funkciám: https://en.cppreference.com/w/c/numeric/math \ No newline at end of file diff --git a/sk2/calculator.c b/sk2/calculator.c index e69de29..53094c2 100644 --- a/sk2/calculator.c +++ b/sk2/calculator.c @@ -0,0 +1,91 @@ +#include "calculator.h" +#include +#include +#include +#include +#include + +// 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; } + +double sinus(double x) { return sin(x); } +double cosinus(double x) { return cos(x); } +double odmocnina(double x) { return sqrt(x); } +double mocnina(double zaklad, double exponent) { return pow(zaklad, exponent); } +double logaritmus(double x) { return log(x); } + +// Funkcia na konverziu infixového výrazu na postfixový (Shunting-yard algoritmus) +void infix_na_postfix(const char *infix, char *postfix) { + char stack[100]; + int top = -1; + int j = 0; + + for (int i = 0; infix[i] != '\0'; i++) { + if (isdigit(infix[i]) || infix[i] == '.') { + postfix[j++] = infix[i]; + } else if (je_operator(infix[i])) { + postfix[j++] = ' '; + while (top != -1 && priorita(stack[top]) >= priorita(infix[i])) { + postfix[j++] = stack[top--]; + postfix[j++] = ' '; + } + stack[++top] = infix[i]; + } else if (infix[i] == '(') { + stack[++top] = infix[i]; + } else if (infix[i] == ')') { + while (top != -1 && stack[top] != '(') { + postfix[j++] = ' '; + postfix[j++] = stack[top--]; + } + top--; // Odstrániť '(' zo zásobníka + } + } + while (top != -1) { + postfix[j++] = ' '; + postfix[j++] = stack[top--]; + } + postfix[j] = '\0'; +} + +// Vyhodnotenie postfixového výrazu +double vyhodnot_postfix(const char *postfix) { + double stack[100]; + int top = -1; + char *token = strtok(strdup(postfix), " "); + + while (token) { + if (isdigit(token[0]) || (token[0] == '-' && isdigit(token[1]))) { + stack[++top] = atof(token); + } else if (je_operator(token[0]) && token[1] == '\0') { + 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; + case '/': stack[++top] = del(a, b); break; + case '^': stack[++top] = mocnina(a, b); break; + } + } + token = strtok(NULL, " "); + } + return stack[top]; +} diff --git a/sk2/calculator.h b/sk2/calculator.h index e69de29..22fe160 100644 --- a/sk2/calculator.h +++ b/sk2/calculator.h @@ -0,0 +1,31 @@ +#ifndef CALCULATOR_H +#define CALCULATOR_H + +#include + +// Konverzia infixového výrazu na postfixový +void infix_na_postfix(const char *infix, char *postfix); + +// Vyhodnotenie postfixového výrazu +double vyhodnot_postfix(const char *postfix); + +// Overenie, či je znak operátor +bool je_operator(char c); + +// Určenie priority operátorov +int priorita(char op); + +// Matematické operácie +double scitaj(double a, double b); +double odcitaj(double a, double b); +double nasob(double a, double b); +double del(double a, double b); + +// Vedecké funkcie +double sinus(double x); +double cosinus(double x); +double odmocnina(double x); +double mocnina(double zaklad, double exponent); +double logaritmus(double x); + +#endif // CALCULATOR_H diff --git a/sk2/main.c b/sk2/main.c index e69de29..941d88f 100644 --- a/sk2/main.c +++ b/sk2/main.c @@ -0,0 +1,19 @@ +#include "calculator.h" +#include +#include + +int main() { + char infix[100], postfix[100]; + printf("Zadajte matematický výraz: "); + fgets(infix, sizeof(infix), stdin); + + // Konverzia na postfixovú notáciu + infix_na_postfix(infix, postfix); + printf("Postfixová notácia: %s\n", postfix); + + // Vyhodnotenie výrazu + double vysledok = vyhodnot_postfix(postfix); + printf("Výsledok: %.2f\n", vysledok); + + return 0; +}