Технологии

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

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

январь 23, 2013 г.

  • Всего ответов: 2

  • Сергей - аватарка

    Сергей

    9-й в Технологиях

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

    январь 23, 2013 г.
  • Сергей - аватарка

    Сергей

    9-й в Технологиях

    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, 2013 г.

Похожие вопросы