Cod sursa(job #1906746)

Utilizator bogdanboboc97Bogdan Boboc bogdanboboc97 Data 6 martie 2017 16:08:48
Problema Evaluarea unei expresii Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 4.14 kb
#include <fstream>
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <typeinfo>
#include <cstring>
#include <stdexcept>

template<typename DataType>
class Calculator{
    public:
        static DataType convert(std::string x)
        {
            //DataType y;
            if(strcmp(typeid(DataType).name(),"double")==0)
                return std::stod(x);
            if(strcmp(typeid(DataType).name(),"float")==0)
                return std::stof(x);
            return std::stoi(x);
        }

        static bool isValidExpresion(std::string e)
        {
            int brackets=0;
            for(size_t i=0;i<e.size();i++)
            {
                if(e[i]=='(')
                {
                    brackets++;
                    continue;
                }
                if(e[i]==')')
                {
                    if(brackets<1)
                        return false;
                    brackets--;
                    continue;
                }
                if(!((e[i]>='0' && e[i]<='9') || std::string("+-.*/").find(e[i])!=std::string::npos))
                    return false;
                if(i==0 && std::string(".*/").find(e[i])!=std::string::npos)
                    return false;
                if(i && std::string("+-.*/").find(e[i])!=std::string::npos && std::string("+-.*/").find(e[i-1])!=std::string::npos)
                    return false;
            }
            return brackets==0;

        }

        static int priority(char x)
        {
            if(x=='+' || x=='-')
                return 1;
            if(x=='*' || x=='/' || x=='%')
                return 2;
            return 0;
        }

        static void solveOp(std::stack< DataType > &Numbers, std::stack< char > &Operators)
        {
            int nr2=Numbers.top();
            Numbers.pop();
            int nr1=Numbers.top();
            Numbers.pop();
            char x=Operators.top();
            Operators.pop();
            if(x=='+')
                Numbers.push(nr1+nr2);
            if(x=='-')
                Numbers.push(nr1-nr2);
            if(x=='*')
                Numbers.push(nr1*nr2);
            if(x=='/')
                Numbers.push(nr1/nr2);
            if(x=='%')
                Numbers.push(nr1%nr2);
        }

        static DataType SolveExpresion(std::string e)
        {
            if(isValidExpresion(e)==false)
                throw std::invalid_argument("Invalid expresion!");
            std::stack< DataType > Numbers;
            std::stack< char > Operators;

            std::vector< std::string > v;
            std::string s;

            for(size_t i=0;i<e.size();i++)
            {
                if((e[i]>='0' && e[i]<='9') || e[i]=='.')
                    s.push_back(e[i]);
                else{
                    if(s.size())
                        v.push_back(s);
                    v.push_back( std::string("")+=e[i] );
                    s.clear();
                }
            }
            if(s.size())
            {
                v.push_back(s);
                s.clear();
            }

            for(size_t i=0;i<v.size();i++)
            {
                if(v[i][0]=='(')
                    Operators.push( v[i][0] );
                else if(v[i][0]==')')
                {
                    while(Operators.top()!='(')
                        solveOp(Numbers,Operators);
                    Operators.pop();
                }
                else{

                    if(priority(v[i][0]))
                    {
                        while(!Operators.empty() && priority(Operators.top()) >= priority(v[i][0]))
                            solveOp(Numbers,Operators);
                        Operators.push(v[i][0]);
                    }
                    else
                        Numbers.push( std::stoi(v[i]) );
                }
            }
            while(!Operators.empty())
                solveOp(Numbers,Operators);
            return Numbers.top();
        }
};

int main()
{

    std::ifstream in("evaluare.in");

    std::string e;
    in>>e;
    in.close();

    std::ofstream out("evaluare.out");
    out<<Calculator<int>::SolveExpresion(e)<<'\n';
    out.close();

    return 0;
}