199 lines
5.1 KiB
C++

#include <iostream>
#include <string>
#include <math.h>
#include <queue>
#include <stack>
using namespace std;
// prototipi
bool jeOperand(char);
bool jeOperator(char);
int prioritetaOperatorja(char);
queue<char> pretvori_niz_v_vrsto(string);
queue<char> pretvorba_infiks_v_postfiks(queue<char>);
double izracunaj_skladovni_stroj(queue<char>);
double izracunaj_izraze(string);
bool jeOperand(char c) {
if (c >= '0' && c <= '9')
return true;
return false;
}
bool jeOperator(char c) {
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')')
return true;
return false;
}
int prioritetaOperatorja(char c) {
switch (c) {
case '(':
return 4;
case ')':
return 4;
case '^':
return 3;
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
default:
return -1;
}
}
queue<char> pretvori_niz_v_vrsto(string izraz) {
queue<char> infiksni_izraz;
// TODO
for (int i = 0; i < izraz.size(); i++) {
if (jeOperand(izraz[i]) || jeOperator(izraz[i])) {
infiksni_izraz.push(izraz[i]);
}
}
return infiksni_izraz;
}
queue<char> pretvorba_infiks_v_postfiks(queue<char> infiksni_izraz) {
queue<char> postfiksni_izraz;
stack<char> pomozni_sklad;
char operator1;
char precitaniPodatek;
while (!infiksni_izraz.empty()) {
precitaniPodatek = infiksni_izraz.front();
infiksni_izraz.pop();
if (precitaniPodatek != ')') {
if (jeOperand(precitaniPodatek)) {
postfiksni_izraz.push(precitaniPodatek);
} else {
if (precitaniPodatek == '(') {
pomozni_sklad.push(precitaniPodatek);
} else {
while (!pomozni_sklad.empty() && pomozni_sklad.top() != '(' && prioritetaOperatorja(precitaniPodatek) <= prioritetaOperatorja(pomozni_sklad.top())) {
operator1 = pomozni_sklad.top();
pomozni_sklad.pop();
postfiksni_izraz.push(operator1);
}
pomozni_sklad.push(precitaniPodatek);
}
}
} else {
operator1 = pomozni_sklad.top();
pomozni_sklad.pop();
while (operator1 != '(') {
postfiksni_izraz.push(operator1);
operator1 = pomozni_sklad.top();
pomozni_sklad.pop();
}
}
}
while (!pomozni_sklad.empty()) {
operator1 = pomozni_sklad.top();
pomozni_sklad.pop();
postfiksni_izraz.push(operator1);
}
return postfiksni_izraz;
}
double izracunaj_skladovni_stroj(queue<char> postfiksni_izraz) {
stack<double> skladovni_stroj;
char precitaniPodatek;
double rezultat, num1, num2;
while (!postfiksni_izraz.empty()) {
precitaniPodatek = postfiksni_izraz.front();
postfiksni_izraz.pop();
if (jeOperand(precitaniPodatek)) {
string tmp_string(1, precitaniPodatek);
skladovni_stroj.push(stod(tmp_string));
} else {
num1 = skladovni_stroj.top();
skladovni_stroj.pop();
num2 = skladovni_stroj.top();
skladovni_stroj.pop();
switch (precitaniPodatek) {
case '^':
rezultat = pow(num2, num1);
break;
case '*':
rezultat = num2 * num1;
break;
case '/':
rezultat = num2 / num1;
break;
case '+':
rezultat = num1 + num2;
break;
case '-':
rezultat = num2 - num1;
break;
}
skladovni_stroj.push(rezultat);
}
}
// na skladu mora ostat samo rezultat
return (skladovni_stroj.size() != 0) ? skladovni_stroj.top() : INT32_MIN;
}
double izracunaj_izraz(string izraz) {
// podprogram pretvori_niz_v_vrsto()
queue<char> infiksni_izraz = pretvori_niz_v_vrsto(izraz);
// podprogram pretvorba_infiks_v_postfiks()
queue<char> postfiksni_izraz = pretvorba_infiks_v_postfiks(infiksni_izraz);
// podprogram izracunaj_skladovni_stroj()
double rezultat = izracunaj_skladovni_stroj(postfiksni_izraz);
return rezultat;
}
int main() {
string izrazi[] = {
"2^(2-2)+1",
"4*( 9 - 5 )",
"2-2*2+2",
"2*6/3-2+2"
};
double rezultati[] = {
2.0,
16.0,
0.0,
4.0
};
int N = sizeof(izrazi) / sizeof(string);
for (int i = 0; i < N; i++) {
double rezultat = izracunaj_izraz(izrazi[i]);
if (rezultati[i] == rezultat)
cout << "OK" << endl;
else
cout << "Napacen rezultat za izraz " << izrazi[i] << ": " << rezultat << " (pricakovan rezultat: " << rezultati[i] << ")." << endl;
}
return 0;
}