sk2 du - kalkulacka
This commit is contained in:
parent
a67b036fc1
commit
0f396051b8
16
sk2/Makefile
Normal file
16
sk2/Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -lm
|
||||||
|
|
||||||
|
all: calculator
|
||||||
|
|
||||||
|
calculator: main.o calculator.o
|
||||||
|
$(CC) main.o calculator.o -o calculator $(CFLAGS)
|
||||||
|
|
||||||
|
main.o: main.c calculator.h
|
||||||
|
$(CC) -c main.c
|
||||||
|
|
||||||
|
calculator.o: calculator.c calculator.h
|
||||||
|
$(CC) -c calculator.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o calculator
|
||||||
25
sk2/README.md
Normal file
25
sk2/README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Vedecká kalkulačka v jazyku C
|
||||||
|
|
||||||
|
## Zadanie
|
||||||
|
Naprogramovať vedeckú kalkulačku, ktorá vyhodnocuje matematické výrazy
|
||||||
|
v infixnej notácii so zátvorkami a vedeckými funkciami.
|
||||||
|
|
||||||
|
## Funkčnosť
|
||||||
|
Program podporuje:
|
||||||
|
- reálne čísla s presnosťou double
|
||||||
|
- sčítanie (+), odčítanie (-), násobenie (*), delenie (/), zátvorky
|
||||||
|
- sin, cos, odmocninu (sqrt), druhú mocninu (pow), log
|
||||||
|
|
||||||
|
## Riešenie
|
||||||
|
Výraz je najprv prekonvertovaný z infixnej do postfixovej notácie
|
||||||
|
(Shunting-yard algoritmus).
|
||||||
|
Postfixový výraz je následne vyhodnotený pomocou zásobníka.
|
||||||
|
|
||||||
|
## Podmienky fungovania
|
||||||
|
- prekladač GCC
|
||||||
|
- knižnica math.h
|
||||||
|
|
||||||
|
## Použité zdroje
|
||||||
|
- Shunting Yard Algorithm - Edsger Dijkstra
|
||||||
|
- Dokumentácia jazyka C
|
||||||
|
- math.h
|
||||||
122
sk2/calculator.c
Normal file
122
sk2/calculator.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "calculator.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define MAX 256
|
||||||
|
#define DEG_TO_RAD(x) ((x) * M_PI / 180.0)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double data[MAX];
|
||||||
|
int top;
|
||||||
|
} DoubleStack;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char data[MAX][10];
|
||||||
|
int top;
|
||||||
|
} StringStack;
|
||||||
|
|
||||||
|
//funckie stacku
|
||||||
|
void push_double(DoubleStack *s, double v) { s->data[++s->top] = v; }
|
||||||
|
double pop_double(DoubleStack *s) { return s->data[s->top--]; }
|
||||||
|
|
||||||
|
void push_string(StringStack *s, const char *v) { strcpy(s->data[++s->top], v); }
|
||||||
|
char *pop_string(StringStack *s) { return s->data[s->top--]; }
|
||||||
|
char *peek_string(StringStack *s) { return s->data[s->top]; }
|
||||||
|
|
||||||
|
//priority operatorov
|
||||||
|
int priority(const char *op) {
|
||||||
|
if (!strcmp(op, "+") || !strcmp(op, "-")) return 1;
|
||||||
|
if (!strcmp(op, "*") || !strcmp(op, "/")) return 2;
|
||||||
|
if (!strcmp(op, "sin") || !strcmp(op, "cos") ||
|
||||||
|
!strcmp(op, "sqrt") || !strcmp(op, "log") ||
|
||||||
|
!strcmp(op, "pow")) return 3;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//infix na postfix
|
||||||
|
int infix_to_postfix(const char *infix, char postfix[][10]) {
|
||||||
|
StringStack ops = {.top = -1};
|
||||||
|
int k = 0;
|
||||||
|
|
||||||
|
for (int i = 0; infix[i]; ) {
|
||||||
|
if (isspace(infix[i])) { i++; continue; }
|
||||||
|
|
||||||
|
if (isdigit(infix[i]) || infix[i] == '.') {
|
||||||
|
char num[10];
|
||||||
|
int j = 0;
|
||||||
|
while (isdigit(infix[i]) || infix[i] == '.')
|
||||||
|
num[j++] = infix[i++];
|
||||||
|
num[j] = '\0';
|
||||||
|
strcpy(postfix[k++], num);
|
||||||
|
}
|
||||||
|
else if (isalpha(infix[i])) {
|
||||||
|
char func[10];
|
||||||
|
int j = 0;
|
||||||
|
while (isalpha(infix[i]))
|
||||||
|
func[j++] = infix[i++];
|
||||||
|
func[j] = '\0';
|
||||||
|
push_string(&ops, func);
|
||||||
|
}
|
||||||
|
else if (infix[i] == '(') {
|
||||||
|
char t[2] = "(";
|
||||||
|
push_string(&ops, t);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (infix[i] == ')') {
|
||||||
|
while (ops.top != -1 && strcmp(peek_string(&ops), "("))
|
||||||
|
strcpy(postfix[k++], pop_string(&ops));
|
||||||
|
pop_string(&ops);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char op[2] = {infix[i++], '\0'};
|
||||||
|
while (ops.top != -1 &&
|
||||||
|
priority(peek_string(&ops)) >= priority(op))
|
||||||
|
strcpy(postfix[k++], pop_string(&ops));
|
||||||
|
push_string(&ops, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ops.top != -1)
|
||||||
|
strcpy(postfix[k++], pop_string(&ops));
|
||||||
|
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
//vypocet postfixu
|
||||||
|
double evaluate_postfix(char postfix[][10], int n) {
|
||||||
|
DoubleStack s = {.top = -1};
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (isdigit(postfix[i][0]) || postfix[i][0] == '.') {
|
||||||
|
push_double(&s, atof(postfix[i]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
double b = pop_double(&s);
|
||||||
|
double a = (!strcmp(postfix[i], "sin") ||
|
||||||
|
!strcmp(postfix[i], "cos") ||
|
||||||
|
!strcmp(postfix[i], "sqrt") ||
|
||||||
|
!strcmp(postfix[i], "log")) ? 0 : pop_double(&s);
|
||||||
|
|
||||||
|
if (!strcmp(postfix[i], "+")) push_double(&s, a + b);
|
||||||
|
else if (!strcmp(postfix[i], "-")) push_double(&s, a - b);
|
||||||
|
else if (!strcmp(postfix[i], "*")) push_double(&s, a * b);
|
||||||
|
else if (!strcmp(postfix[i], "/")) push_double(&s, a / b);
|
||||||
|
else if (!strcmp(postfix[i], "sin")) push_double(&s, sin(DEG_TO_RAD(b)));
|
||||||
|
else if (!strcmp(postfix[i], "cos")) push_double(&s, cos(DEG_TO_RAD(b)));
|
||||||
|
else if (!strcmp(postfix[i], "sqrt")) push_double(&s, sqrt(b));
|
||||||
|
else if (!strcmp(postfix[i], "log")) push_double(&s, log10(b));
|
||||||
|
else if (!strcmp(postfix[i], "pow")) push_double(&s, pow(a, b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pop_double(&s);
|
||||||
|
}
|
||||||
|
|
||||||
|
double evaluate_expression(const char *expression) {
|
||||||
|
char postfix[MAX][10];
|
||||||
|
int n = infix_to_postfix(expression, postfix);
|
||||||
|
return evaluate_postfix(postfix, n);
|
||||||
|
}
|
||||||
6
sk2/calculator.h
Normal file
6
sk2/calculator.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef CALCULATOR_H
|
||||||
|
#define CALCULATOR_H
|
||||||
|
|
||||||
|
double evaluate_expression(const char *expression);
|
||||||
|
|
||||||
|
#endif
|
||||||
14
sk2/main.c
Normal file
14
sk2/main.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "calculator.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char expr[256];
|
||||||
|
|
||||||
|
printf("Zadaj vyraz: ");
|
||||||
|
fgets(expr, sizeof(expr), stdin);
|
||||||
|
|
||||||
|
double result = evaluate_expression(expr);
|
||||||
|
printf("Vysledok: %.2f\n", result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user