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