199 lines
5.1 KiB
C++
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;
|
|
}
|
|
|