Вычислить арифметическое выражение, выданное в... - вопрос №529428

Вычислить арифметическое выражение, выданное в текстовой строке (стринге). Выражение может содержать положительные натуральные и любые (реальные) числа, символы бинарных операций сложения (+), вычитания (-), умножения (*) и деления (/), кронштейны (возможно вложенные), чтобы изменить приоритет операций. Если невозможно вычислить выражение — вывод ошибки. Например: “12.5*2+4*1.5” – 31 “10*(15+35)-2.5*10” – 475 Пожалуйста, откликнитесь люди, те кто в этом разбирается, очень нужнапомощь.

23.01.13
2 ответа

Ответы

это делается через обратную польскую нотацию. На каком языке нужно писать? (c++, pascal)

23.01.13

1. Поддерживаются только операции + — * / и задание приоритета при помощи скобок (я так понимаю, они понимались под кронштейнами).

2. Унарный минус не поддерживается. то есть, например 2 * (-3) не вычислится а вот 2 * (0-3) вычислится.

3. Никакого контроля за корректностью выражений нету. То есть если написать что-то некрректное — скорее всего будет «segmentation fault»

Ниже — собственно программа.

#include<iostream>
#include<string>
#include<stack>
#include<list>
#include<stdlib.h>
#include<vector>
#include<stdio.h>

using namespace std;

// function for check a priority for operation
unsigned checkPriority(char op) {
if (op == '*' || op == '/')
return 3;
else if (op == '+' || op == '-')
return 2;
else if (op == '(')
return 1;
}

int main() {
// get expression
string s;
cout << «enter a expression, please. Then press ENTER »;
getline(cin, s);

// remove a whitespaces from string
unsigned i = 0;
while (i < s.length()) {
if (s[i] == ' ') {
s.erase(i, 1);
continue;
}
i++;
};

// reverse polish record
stack<char> opz;
vector<string> out;

i = 0;
bool b = false;

// temporrary variable for next item
string tmps = "";

// parse a string and push items to stack
while (i < s.length()) {

if ((s[i] >= '0' && s[i] <='9') || s[i] == '.') {
tmps += s[i];
if (i == (s.length() — 1)) {
// store a value
out.push_back(tmps);
tmps = "";
break;
}
} else {
if (tmps != "") {
// store a value
out.push_back(tmps);
tmps = "";
}

if ((!opz.size() || s[i] == '(' || (checkPriority(s[i]) >= checkPriority(opz.top()))) && (s[i] != ')')) {
// if stack is empty or priority of current operator is greather of priority of top element
opz.push(s[i]);
} else {
if (s[i] == ')') {
while (opz.size() && (opz.top() != '(')) {
char c = opz.top();
string s = " ";
s[0] = c;
out.push_back(s);
opz.pop();
}
opz.pop();
} else {
while (opz.size() && checkPriority(s[i]) < checkPriority(opz.top())) {
char c = opz.top();
string s = " ";
s[0] = c;
out.push_back(s);
opz.pop();
}
opz.push(s[i]);
}
}
}

// store a last number
if (i == (s.length() — 1))
if (tmps != "")
out.push_back(tmps);
i++;
}

// store last operations
while (opz.size()) {
char c = opz.top();
string s = " ";
s[0] = c;
out.push_back(s);
opz.pop();
}

cout << «expression in reverse polish record:» << endl;
for (vector<string>::iterator i = out.begin(); i != out.end(); i++)
cout << *i << endl;

// calculate a value
stack<string> calc;
unsigned j = 0;
while (j < out.size()) {
string i;
i = out[j];
j++;
if (i != "+" && i != "-" && i != "*" && i != "/") {
// it is a number — push it
calc.push(i);
} else {
// it is a operation
double op2 = atof(calc.top().c_str());
calc.pop();
double op1 = atof(calc.top().c_str());
calc.pop();
double res = 0;
if (i == "+")
res = op1 + op2;
else if (i == "-")
res = op1 — op2;
else if (i == "*")
res = op1 * op2;
else if (i == "/")
res = op1 / op2;

char str_res[1024];
sprintf(str_res, "%f", res);
calc.push(str_res);
}
}

// type a result
cout << «Result: » << calc.top() << endl;

return 0;
}

23.01.13
Посмотреть всех экспертов из раздела Технологии > Delphi
Пользуйтесь нашим приложением Доступно на Google Play Загрузите в App Store