Search code examples
c++functionmathexpressionevaluate

Implementation of a function that evaluates simple mathematical expressions. (C++)


I am trying to write a function that evaluates simple mathematical expressions (only four operations). I used stack and vector to do this. But stack operations don't behave as I expect. I couldn't find the cause. I am open to different solutions.

The function should take a string like this:

"5 * 44 + 3 / 2 * 4 - 12"

And return the result as a double.

#include <iostream>
#include <vector>
#include <stack>
#include <string>
#include <cstdlib>

using namespace std;

vector<string> split(const std::string& str, char delim = ' ')
{
    vector<string> elements;
    stringstream ss(str);
    string token;
    while (getline(ss, token, delim)) {
        elements.push_back(token);
    }

    return elements;
}


double evaluate(string operation)
{
    vector<string> values = split(operation, ' ');
    stack<string> result_stack;
    double result = 0;

    for(unsigned int i = 0; i < values.size(); i++){
        if(values[i] == "*"){
            double mini_result = stod(result_stack.top()) * stod(values[i+1]);
            result_stack.pop();
            i++;
            result_stack.push(to_string(mini_result));
        }
        else if(values[i] == "/"){
            double mini_result = stod(result_stack.top()) / stod(values[i+1]);
            result_stack.pop();
            i++;
            result_stack.push(to_string(mini_result));
        }
        else{
            result_stack.push(values[i]);
        }
    }

    for(unsigned int i = 0; i<result_stack.size(); i++){
        if(result_stack.top() == "-"){
            result_stack.pop();
            result = stod(result_stack.top()) - result;
            result_stack.pop();
        }
        else if(result_stack.top() == "+"){
            result_stack.pop();
            result += stod(result_stack.top());
            result_stack.pop();
        }
        else{
            result += stod(result_stack.top());
            result_stack.pop();
        }
    }

    return result;

}




int main()
{

    cout<<evaluate("5 * 44 + 3 / 2 * 4 - 12");
}

Before the second for loop, values in the result_stack should be like this for this example. "12 | - | 6 | + | 220" . And the returning value should be 214.

But before the second for loop, stack contains only "12 | - | 6" values. "+" and "220" values are not there. Some extra pops occur which I don't expect.

stack content should be like this for this example


Solution

  • Answered here: answer of the question

    Completed code is here:

    #include <iostream>
    #include <vector>
    #include <sstream>
    #include <string>
    #include <stack>
    
    using namespace std;
    
    string trim(const string& str)
    {
        size_t first = str.find_first_not_of(' ');
        if (string::npos == first)
        {
            return str;
        }
        size_t last = str.find_last_not_of(' ');
        return str.substr(first, (last - first + 1));
    }
    
    vector<string> split(const std::string& str, char delim = ' ')
    {
        vector<string> elements;
        stringstream ss(str);
        string token;
        while (getline(ss, token, delim)) {
            elements.push_back(token);
        }
    
        return elements;
    }
    
    double evaluate(string operation)
    {
        vector<string> values = split(operation, ' ');
        vector<string> result_vector;
        double result = 0;
    
        for(unsigned int i = 0; i < values.size(); i++){
            if(values[i] == "*"){
                double mini_result = stod(result_vector.back()) * stod(values[i+1]);
                result_vector.pop_back();
                i++;
                result_vector.push_back(to_string(mini_result));
            }
            else if(values[i] == "/"){
                double mini_result = stod(result_vector.back()) / stod(values[i+1]);
                result_vector.pop_back();
                i++;
                result_vector.push_back(to_string(mini_result));
            }
            else{
                result_vector.push_back(values[i]);
            }
        }
    
        auto iterator = result_vector.begin();
        while(iterator != result_vector.end()){
            if(*iterator == "-"){
                iterator++;
                result -= stod(*iterator);
            }
            else if(*iterator == "+"){
                iterator++;
                result += stod(*iterator);
            }
            else{
                result += stod(*iterator);
            }
            iterator++;
        }
        return result;
    }
    
    
    int main()
    {
        cout<<evaluate("5 * 44 + 3 / 2 * 4 - 12");
    }