This commit is contained in:
Džubara 2025-01-31 19:14:04 +01:00
parent 0f9977f603
commit e7b4ea33f3
5 changed files with 204 additions and 0 deletions

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,91 @@
#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; }
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];
}

View File

@ -0,0 +1,31 @@
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <stdbool.h>
// 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

View File

@ -0,0 +1,19 @@
#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
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;
}