Cod sursa(job #1727167)

Utilizator dorumusuroiFMI - Doru Musuroi dorumusuroi Data 9 iulie 2016 22:57:17
Problema Evaluarea unei expresii Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.68 kb
#include <fstream>
#include <iostream>
#include <cassert>
#include <unordered_map>
#include <sstream>
using namespace std;

typedef int (*CalcFunction)(string, string);
typedef unordered_map<string, CalcFunction> calc_map;

calc_map operation;

#define cout g

bool contains(string source, char target){
    for(unsigned int i = 0; i < source.size(); ++i)
        if(source[i] == target)
            return true;
    return false;
}

pair< pair<string, string>, string> parse(string s, string operators){
    int parantheses = 0;
    string left ="", right="";
    string op ="";
    bool opMet = false;
    for(unsigned int i = 0; i < s.size(); ++i){
        if(s[i] == '('){
            parantheses++;
            if(contains(operators, '+')){
                if(opMet)
                    right += s[i];
                else
                    left += s[i];
            }
            if(parantheses == 1)
                continue;
        }

        if(s[i] == ')'){
            parantheses--;
            if(contains(operators, '+')){
                if(opMet)
                    right += s[i];
                else
                    left += s[i];
            }
            if(parantheses == 0)
                continue;
        }

        if(parantheses == 0){
            if(contains(operators, s[i]) && !opMet){
                opMet = true;
                op = s[i];
            }else{
                if(!opMet)
                    left += s[i];
                else
                    right += s[i];
            }
        }
        else{
            if(!opMet)
                left += s[i];
            else
                right += s[i];
        }
    }
    return make_pair(make_pair(left, right), op);
}

pair<int, int> parseValues(string left, string right){
    pair< pair<string, string>, string> leftParse, rightParse;
    leftParse = parse(left, "+-");
    if(leftParse.second == "")
        leftParse = parse(left, "*/");
    rightParse = parse(right, "+-");
    if(rightParse.second == "")
        rightParse = parse(right, "*/");
    int leftResult, rightResult;
    if(leftParse.second == ""){
        stringstream ss;
        ss << leftParse.first.first;
        ss >> leftResult;
    }else{
        leftResult = (*(operation[leftParse.second]))(leftParse.first.first, leftParse.first.second);
    }
    if(rightParse.second == ""){
        stringstream ss;
        ss << rightParse.first.first;
        ss >> rightResult;
    }else{
        rightResult = (*(operation[rightParse.second]))(rightParse.first.first, rightParse.first.second);
    }
    return make_pair(leftResult, rightResult);
}

int sum(string left, string right){
    pair<int, int> rez = parseValues(left, right);

    return rez.first + rez.second;
}
int diff(string left, string right){
    pair<int, int> rez = parseValues(left, right);

    return rez.first - rez.second;
}
int division(string left, string right){
    pair<int, int> rez = parseValues(left, right);

    return rez.first / rez.second;
}

int mult(string left, string right){
    pair<int, int> rez = parseValues(left, right);

    return rez.first * rez.second;
}

int main()
{
    string expression;
    ifstream f("evaluare.in");
    ofstream g("evaluare.out");
    f >> expression;
    f.close();
    operation.insert(make_pair("+", sum));
    operation.insert(make_pair("-", diff));
    operation.insert(make_pair("/", division));
    operation.insert(make_pair("*", mult));

    pair<pair<string, string>, string> inter = parse(expression, "+-");
    if(inter.second == "")
        inter = parse(expression, "*/");
    if(inter.second == ""){
        cout << inter.first.first;
    }else{
        cout << (*(operation[inter.second]))(inter.first.first, inter.first.second);
    }
    return 0;
}