Skip to main content
Commonmark migration
Source Link
  1. It first does the deepest brackets.

    It first does the deepest brackets.

    (10 + (20 * -14))
    
  2. Then, since there's a minus it multiplies the result of the brackets by -1.

    (10 + (-280))
    
  3. Then it does the multiply in the brackets.

    (-270)
    
  4. Then it does the addition with the 10 and the -280.

(10 + (20 * -14))
  1. Then, since there's a minus it multiplies the result of the brackets by -1.
(10 + (-280))
  1. Then it does the multiply in the brackets.
(-270)
  1. Then it does the addition with the 10 and the -280.
  1. It first does the deepest brackets.
(10 + (20 * -14))
  1. Then, since there's a minus it multiplies the result of the brackets by -1.
(10 + (-280))
  1. Then it does the multiply in the brackets.
(-270)
  1. Then it does the addition with the 10 and the -280.
  1. It first does the deepest brackets.

    (10 + (20 * -14))
    
  2. Then, since there's a minus it multiplies the result of the brackets by -1.

    (10 + (-280))
    
  3. Then it does the multiply in the brackets.

    (-270)
    
  4. Then it does the addition with the 10 and the -280.

Tweeted twitter.com/#!/StackCodeReview/status/489105372343717888
added 49 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Can you rate my C++ Expression Evaluator out of 10? Four-function expression evaluator

It understands, + +, --, //, **, brackets and the order of operations. I haven't put a modulus operator in the evaluator because I'm going to make a function for modulus instead.

(10 + (20 * - (5 + 9)))

(10 + (20 * - (5 + 9)))

I'd just like to know whether there are any ways I can improve my expression evaluator and whether there are any complicated expressions that don't evaluate correctly. Also

Also, is there a better way than using the time command on OSX to find out how fast it evaluates because the time command only does to 3 decimal places so it's not accurate enough.?

(10 + (20 * - (14)))
(10 + (20 * - (14)))
  1. It first does the deepest brackets.

    (10 + (20 * -14))

  2. Then, since there's a minus it multiplies the result of the brackets by -1.

    (10 + (-280))

  3. Then it does the multiply in the brackets.

    (-270)

  4. Then it does the addition with the 10 and the -280.

    #include #include #include #include #include #include #include #include #include

    using namespace std;

    vector rdo_num_stack; int opp_count = 0;

    bool rdo_ws(char c) { if (c != ' ') return 0; else return 1; }

    char rdo_expr_item_type(char c) {

     switch(c) {
         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         case '.':
             c = 'n';
             break;
         case '+':
         case '-':
         case '*':
         case '/':
             c = 'o';
             break;
         case '(':
         case ')':
             c = 'b';
             break;
     }
    
     return c;
    

    }

    string rdo_opp_to_string(char opp) {

     string o = "";
    
     switch(opp) {
         case '+':
             o = "+";
             break;
         case '-':
             o = "-";
             break;
         case '/':
             o = "/";
             break;
         case '*':
             o = "*";
             break;
         case '(':
             o = "(";
             break;
         case ')':
             o = ")";
             break;
     }
    
     return o;
    

    }

    bool rdo_is_num(string is_num) { if (is_num == "+" or is_num == "-" or is_num == "/" or is_num == "*" or is_num == "(" or is_num == ")") { return 0; } return 1; }

    void rdo_count_opp(bool to_count_or_not) { if (to_count_or_not == 1) opp_count++; }

    string rdo_eval(string expr) {

     string result;
     string num_holder = "";
     string temp_result = "";
     string num1 = "";
     string num2 = "";
     int n2 = 0;
     int i;
     int iter;
     int bcount = 0;
     int depth = 0;
     int current_depth = 0;
     int diff = 0;
     int diff2 = 0;
     int current_b = 0;
     int minus_count = 0;
     int minus_start = 0;
     int plus_count = 0;
     int plus_start = 0;
     bool found_end = 0;
     bool got_diff = 0;
     bool to_inverse = 0;
     bool do_calc = 0;
    
     for (i = 0; i < expr.length();i++) {
    
         if (!rdo_ws(expr[i])) {
             if (rdo_expr_item_type(expr[i]) == 'n' or rdo_expr_item_type(expr[i]) == 'o' or rdo_expr_item_type(expr[i]) == 'b') {
    
                 if (rdo_expr_item_type(expr[i]) == 'n') {
    
                     num_holder += expr[i];
    
                 } else if (rdo_expr_item_type(expr[i]) == 'o') {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
    
                 } else {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
                     bcount++;
    
                 }
    
             } else {
                 cout << "Invalid character in expression" << endl;
                 exit(0);
             }
    
             if (i == expr.length()-1 and num_holder != "") {
    
                 rdo_num_stack.push_back(num_holder);
                 num_holder = "";
    
             }
    
         }
    
     }
    
     if (bcount % 2 != 0) {
         cout << "Extra / Missing parens." << endl;
         exit(0);
     } else {
         bcount /= 2;
     }
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         if (rdo_num_stack[i] == "(") {
             current_b++;
    
         }
         if (current_b == bcount and !found_end) {
             if (i == 1)
                 depth = 0;
             else
                 depth = i;
             found_end = 1;
         }
         if (rdo_num_stack[i] == ")" and found_end and !got_diff) {
             diff = i - depth;
             got_diff = 1;
         }
     }
    
    
     for (i = depth; i < depth+diff; i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "-") {
                 rdo_count_opp(0);
             } else if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "+") {
                 rdo_count_opp(0);
             } else {
                 rdo_count_opp(1);
             }
         }
    
     }
    
    
     for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i] == "+" and rdo_num_stack[i+1] == "-") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff -= 1;
         }
         if (rdo_num_stack[i] == "-" and rdo_num_stack[i+1] == "+") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
             diff -= 1;
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "-") {
    
             minus_count++;
    
             if (minus_start == 0) {
                 minus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "-") {
    
             if (minus_count != 0 and minus_count % 2 == 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[minus_start+minus_count] != "" and rdo_num_stack[minus_start+minus_count][0] != '+') {
                 rdo_num_stack[minus_start+minus_count] = "+" + rdo_num_stack[minus_start+minus_count];
                 }
                 minus_start = 0;
                 minus_count = 0;
    
             } else if (minus_count != 0 and minus_count % 2 != 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 rdo_num_stack[minus_start+minus_count] = "-" + rdo_num_stack[minus_start+minus_count];
                 minus_start = 0;
                 minus_count = 0;
    
             }
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "+") {
    
             plus_count++;
    
             if (plus_start == 0) {
                 plus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "+") {
             for (iter = plus_start;iter < plus_start+plus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[plus_start+plus_count] != "" and rdo_num_stack[plus_start+plus_count][0] != '(') {
                 rdo_num_stack[plus_start+plus_count] = "+" + rdo_num_stack[plus_start+plus_count];
                 }
    
                 plus_start = 0;
                 plus_count = 0;
         }
     }
    
     for (i = depth+diff;i >= depth;i--) {
         if (i - 1 >= depth) {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] != "(" and rdo_num_stack[i][0] != '+' and rdo_num_stack[i][0] != '-'  and rdo_num_stack[i] != "") {
                 rdo_num_stack[i] = "+" + rdo_num_stack[i];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
         }
         if (rdo_num_stack[i] == "") {
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
         }
     }
    
     div_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "/") {
                 result = to_string(stof(rdo_num_stack[i-1]) / stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto div_loop;
             }
     }
    
     mul_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "*") {
                 result = to_string(stof(rdo_num_stack[i-1]) * stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto mul_loop;
             }
    
    
     }
    
    
     minus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '-' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
    
             goto minus_loop;
    
         }
    
     } 
    
     plus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '+' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=2;
             goto plus_loop;
    
         }
    
     }
    
     opp_count = 0;
    
     for (i = 0; i < rdo_num_stack.size();i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
    
             opp_count++;
    
         }
    
     }
    
     if (opp_count > 0) {
    
         for (i = depth; i < depth+diff;i++) {
             if (rdo_num_stack[i] == "(" and rdo_num_stack[i+2] == ")") {
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
    
             }
         }
    
     }
    
     expr = "";
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
     }
    
     expr = "";
     bcount = 0;
     depth = 0;
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
         if (rdo_num_stack[i] == "(") {
             bcount++;
             depth = i;
         }
     }
    
     result = rdo_num_stack[depth+1];
    
     rdo_num_stack.clear();
     if (opp_count > 0)
         return rdo_eval(expr);
     else
         expr = to_string(stoi(result));
         return expr;
    

    }

    int main() { int i;

     cout << rdo_eval("(10 + (20 * - (5 + 9)))") << endl << endl;
    
     return 0;
    

    }

  5. It first does the deepest brackets.
(10 + (20 * -14))
  1. Then, since there's a minus it multiplies the result of the brackets by -1.
(10 + (-280))
  1. Then it does the multiply in the brackets.
(-270)
  1. Then it does the addition with the 10 and the -280.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <functional>

using namespace std;

vector<string> rdo_num_stack;
int opp_count = 0;

bool rdo_ws(char c) {
    if (c != ' ')
        return 0;
    else
        return 1;
}

char rdo_expr_item_type(char c) {

    switch(c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '.':
            c = 'n';
            break;
        case '+':
        case '-':
        case '*':
        case '/':
            c = 'o';
            break;
        case '(':
        case ')':
            c = 'b';
            break;
    }

    return c;

}

string rdo_opp_to_string(char opp) {

    string o = "";

    switch(opp) {
        case '+':
            o = "+";
            break;
        case '-':
            o = "-";
            break;
        case '/':
            o = "/";
            break;
        case '*':
            o = "*";
            break;
        case '(':
            o = "(";
            break;
        case ')':
            o = ")";
            break;
    }

    return o;

}

bool rdo_is_num(string is_num) {
    if (is_num == "+" or
        is_num == "-" or
        is_num == "/" or
        is_num == "*" or
        is_num == "(" or
        is_num == ")") {
        return 0;
    }
    return 1;
}

void rdo_count_opp(bool to_count_or_not) {
    if (to_count_or_not == 1)
        opp_count++;
}

string rdo_eval(string expr) {

    string result;
    string num_holder = "";
    string temp_result = "";
    string num1 = "";
    string num2 = "";
    int n2 = 0;
    int i;
    int iter;
    int bcount = 0;
    int depth = 0;
    int current_depth = 0;
    int diff = 0;
    int diff2 = 0;
    int current_b = 0;
    int minus_count = 0;
    int minus_start = 0;
    int plus_count = 0;
    int plus_start = 0;
    bool found_end = 0;
    bool got_diff = 0;
    bool to_inverse = 0;
    bool do_calc = 0;

    for (i = 0; i < expr.length();i++) {

        if (!rdo_ws(expr[i])) {
            if (rdo_expr_item_type(expr[i]) == 'n' or rdo_expr_item_type(expr[i]) == 'o' or rdo_expr_item_type(expr[i]) == 'b') {

                if (rdo_expr_item_type(expr[i]) == 'n') {

                    num_holder += expr[i];

                } else if (rdo_expr_item_type(expr[i]) == 'o') {

                    if (num_holder != "") {

                        rdo_num_stack.push_back(num_holder);
                        num_holder = "";

                    }

                    rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));

                } else {

                    if (num_holder != "") {

                        rdo_num_stack.push_back(num_holder);
                        num_holder = "";

                    }

                    rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
                    bcount++;

                }
            
            } else {
                cout << "Invalid character in expression" << endl;
                exit(0);
            }

            if (i == expr.length()-1 and num_holder != "") {

                rdo_num_stack.push_back(num_holder);
                num_holder = "";

            }

        }

    }

    if (bcount % 2 != 0) {
        cout << "Extra / Missing parens." << endl;
        exit(0);
    } else {
        bcount /= 2;
    }

    for (i = 0; i < rdo_num_stack.size();i++) {
        if (rdo_num_stack[i] == "(") {
            current_b++;
            
        }
        if (current_b == bcount and !found_end) {
            if (i == 1)
                depth = 0;
            else
                depth = i;
            found_end = 1;
        }
        if (rdo_num_stack[i] == ")" and found_end and !got_diff) {
            diff = i - depth;
            got_diff = 1;
        }
    }


    for (i = depth; i < depth+diff; i++) {

        if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
            if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "-") {
                rdo_count_opp(0);
            } else if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "+") {
                rdo_count_opp(0);
            } else {
                rdo_count_opp(1);
            }
        }
    
    }


    for (i = depth; i <= depth+diff;i++) {

        if (rdo_num_stack[i] == "+" and rdo_num_stack[i+1] == "-") {

            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff -= 1;
        }
        if (rdo_num_stack[i] == "-" and rdo_num_stack[i+1] == "+") {

            rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
            diff -= 1;
        }
    }
        
    for (i = depth; i <= depth+diff;i++) {
        if (rdo_num_stack[i] == "-") {

            minus_count++;

            if (minus_start == 0) {
                minus_start = i;
            }
            
        }
        if (rdo_num_stack[i] != "-") {

            if (minus_count != 0 and minus_count % 2 == 0) {
                
                for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                if (rdo_num_stack[minus_start+minus_count] != "" and rdo_num_stack[minus_start+minus_count][0] != '+') {
                rdo_num_stack[minus_start+minus_count] = "+" + rdo_num_stack[minus_start+minus_count];
                }
                minus_start = 0;
                minus_count = 0;

            } else if (minus_count != 0 and minus_count % 2 != 0) {
                
                for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                rdo_num_stack[minus_start+minus_count] = "-" + rdo_num_stack[minus_start+minus_count];
                minus_start = 0;
                minus_count = 0;

            }
        }
    }

    for (i = depth; i <= depth+diff;i++) {
        if (rdo_num_stack[i] == "+") {

            plus_count++;

            if (plus_start == 0) {
                plus_start = i;
            }
            
        }
        if (rdo_num_stack[i] != "+") {
            for (iter = plus_start;iter < plus_start+plus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                if (rdo_num_stack[plus_start+plus_count] != "" and rdo_num_stack[plus_start+plus_count][0] != '(') {
                rdo_num_stack[plus_start+plus_count] = "+" + rdo_num_stack[plus_start+plus_count];
                }

                plus_start = 0;
                plus_count = 0;
        }
    }

    for (i = depth+diff;i >= depth;i--) {
        if (i - 1 >= depth) {
            if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] != "(" and rdo_num_stack[i][0] != '+' and rdo_num_stack[i][0] != '-'  and rdo_num_stack[i] != "") {
                rdo_num_stack[i] = "+" + rdo_num_stack[i];
            }
            if (rdo_num_stack[i] == "/" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
            }
            if (rdo_num_stack[i] == "/" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
            }
            if (rdo_num_stack[i] == "*" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
            }
            if (rdo_num_stack[i] == "*" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
            }
        }
        if (rdo_num_stack[i] == "") {
            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=1;
        }
    }

    div_loop:for (i = depth+diff;i >= depth;i--) {
            
            if (rdo_num_stack[i] == "/") {
                result = to_string(stof(rdo_num_stack[i-1]) / stof(rdo_num_stack[i+1]));
                if (result[0] != '+' and result[0] != '-') {
                    result = "+" + result;
                }
                rdo_num_stack[i-1] = result;
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                diff -= 2;

                goto div_loop;
            }
    }

    mul_loop:for (i = depth+diff;i >= depth;i--) {
            
            if (rdo_num_stack[i] == "*") {
                result = to_string(stof(rdo_num_stack[i-1]) * stof(rdo_num_stack[i+1]));
                if (result[0] != '+' and result[0] != '-') {
                    result = "+" + result;
                }
                rdo_num_stack[i-1] = result;
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                diff -= 2;

                goto mul_loop;
            }

            
    }
  

    minus_loop:for (i = depth; i <= depth+diff;i++) {
        
        if (rdo_num_stack[i][0] == '-' and rdo_num_stack[i-1] != "(") {
            
            result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
            if (result[0] != '+' and result[0] != '-') {
                result = "+" + result;
            }
            rdo_num_stack[i-1] = result;
            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=1;
            
            goto minus_loop;

        }

    } 

    plus_loop:for (i = depth; i <= depth+diff;i++) {
        
        if (rdo_num_stack[i][0] == '+' and rdo_num_stack[i-1] != "(") {
            
            result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
            if (result[0] != '+' and result[0] != '-') {
                result = "+" + result;
            }
            rdo_num_stack[i-1] = result;

            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=2;
            goto plus_loop;

        }

    }
 
    opp_count = 0;

    for (i = 0; i < rdo_num_stack.size();i++) {
        
        if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {

            opp_count++;

        }

    }

    if (opp_count > 0) {

        for (i = depth; i < depth+diff;i++) {
            if (rdo_num_stack[i] == "(" and rdo_num_stack[i+2] == ")") {
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i+1);

            }
        }

    }

    expr = "";

    for (i = 0; i < rdo_num_stack.size();i++) {
        expr += rdo_num_stack[i];
    }

    expr = "";
    bcount = 0;
    depth = 0;
    for (i = 0; i < rdo_num_stack.size();i++) {
        expr += rdo_num_stack[i];
        if (rdo_num_stack[i] == "(") {
            bcount++;
            depth = i;
        }
    }
    
    result = rdo_num_stack[depth+1];

    rdo_num_stack.clear();
    if (opp_count > 0)
        return rdo_eval(expr);
    else
        expr = to_string(stoi(result));
        return expr;
}

int main() {
    int i;


    cout << rdo_eval("(10 + (20 * - (5 + 9)))") << endl << endl;

    return 0;
}

Can you rate my C++ Expression Evaluator out of 10?

It understands, +, -, /, *, brackets and the order of operations. I haven't put a modulus operator in the evaluator because I'm going to make a function for modulus instead.

(10 + (20 * - (5 + 9)))

I'd just like to know whether there are any ways I can improve my expression evaluator and whether there are any complicated expressions that don't evaluate correctly. Also, is there a better way than using the time command on OSX to find out how fast it evaluates because the time command only does to 3 decimal places so it's not accurate enough.

(10 + (20 * - (14)))
  1. It first does the deepest brackets.

    (10 + (20 * -14))

  2. Then, since there's a minus it multiplies the result of the brackets by -1.

    (10 + (-280))

  3. Then it does the multiply in the brackets.

    (-270)

  4. Then it does the addition with the 10 and the -280.

    #include #include #include #include #include #include #include #include #include

    using namespace std;

    vector rdo_num_stack; int opp_count = 0;

    bool rdo_ws(char c) { if (c != ' ') return 0; else return 1; }

    char rdo_expr_item_type(char c) {

     switch(c) {
         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         case '.':
             c = 'n';
             break;
         case '+':
         case '-':
         case '*':
         case '/':
             c = 'o';
             break;
         case '(':
         case ')':
             c = 'b';
             break;
     }
    
     return c;
    

    }

    string rdo_opp_to_string(char opp) {

     string o = "";
    
     switch(opp) {
         case '+':
             o = "+";
             break;
         case '-':
             o = "-";
             break;
         case '/':
             o = "/";
             break;
         case '*':
             o = "*";
             break;
         case '(':
             o = "(";
             break;
         case ')':
             o = ")";
             break;
     }
    
     return o;
    

    }

    bool rdo_is_num(string is_num) { if (is_num == "+" or is_num == "-" or is_num == "/" or is_num == "*" or is_num == "(" or is_num == ")") { return 0; } return 1; }

    void rdo_count_opp(bool to_count_or_not) { if (to_count_or_not == 1) opp_count++; }

    string rdo_eval(string expr) {

     string result;
     string num_holder = "";
     string temp_result = "";
     string num1 = "";
     string num2 = "";
     int n2 = 0;
     int i;
     int iter;
     int bcount = 0;
     int depth = 0;
     int current_depth = 0;
     int diff = 0;
     int diff2 = 0;
     int current_b = 0;
     int minus_count = 0;
     int minus_start = 0;
     int plus_count = 0;
     int plus_start = 0;
     bool found_end = 0;
     bool got_diff = 0;
     bool to_inverse = 0;
     bool do_calc = 0;
    
     for (i = 0; i < expr.length();i++) {
    
         if (!rdo_ws(expr[i])) {
             if (rdo_expr_item_type(expr[i]) == 'n' or rdo_expr_item_type(expr[i]) == 'o' or rdo_expr_item_type(expr[i]) == 'b') {
    
                 if (rdo_expr_item_type(expr[i]) == 'n') {
    
                     num_holder += expr[i];
    
                 } else if (rdo_expr_item_type(expr[i]) == 'o') {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
    
                 } else {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
                     bcount++;
    
                 }
    
             } else {
                 cout << "Invalid character in expression" << endl;
                 exit(0);
             }
    
             if (i == expr.length()-1 and num_holder != "") {
    
                 rdo_num_stack.push_back(num_holder);
                 num_holder = "";
    
             }
    
         }
    
     }
    
     if (bcount % 2 != 0) {
         cout << "Extra / Missing parens." << endl;
         exit(0);
     } else {
         bcount /= 2;
     }
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         if (rdo_num_stack[i] == "(") {
             current_b++;
    
         }
         if (current_b == bcount and !found_end) {
             if (i == 1)
                 depth = 0;
             else
                 depth = i;
             found_end = 1;
         }
         if (rdo_num_stack[i] == ")" and found_end and !got_diff) {
             diff = i - depth;
             got_diff = 1;
         }
     }
    
    
     for (i = depth; i < depth+diff; i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "-") {
                 rdo_count_opp(0);
             } else if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "+") {
                 rdo_count_opp(0);
             } else {
                 rdo_count_opp(1);
             }
         }
    
     }
    
    
     for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i] == "+" and rdo_num_stack[i+1] == "-") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff -= 1;
         }
         if (rdo_num_stack[i] == "-" and rdo_num_stack[i+1] == "+") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
             diff -= 1;
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "-") {
    
             minus_count++;
    
             if (minus_start == 0) {
                 minus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "-") {
    
             if (minus_count != 0 and minus_count % 2 == 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[minus_start+minus_count] != "" and rdo_num_stack[minus_start+minus_count][0] != '+') {
                 rdo_num_stack[minus_start+minus_count] = "+" + rdo_num_stack[minus_start+minus_count];
                 }
                 minus_start = 0;
                 minus_count = 0;
    
             } else if (minus_count != 0 and minus_count % 2 != 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 rdo_num_stack[minus_start+minus_count] = "-" + rdo_num_stack[minus_start+minus_count];
                 minus_start = 0;
                 minus_count = 0;
    
             }
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "+") {
    
             plus_count++;
    
             if (plus_start == 0) {
                 plus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "+") {
             for (iter = plus_start;iter < plus_start+plus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[plus_start+plus_count] != "" and rdo_num_stack[plus_start+plus_count][0] != '(') {
                 rdo_num_stack[plus_start+plus_count] = "+" + rdo_num_stack[plus_start+plus_count];
                 }
    
                 plus_start = 0;
                 plus_count = 0;
         }
     }
    
     for (i = depth+diff;i >= depth;i--) {
         if (i - 1 >= depth) {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] != "(" and rdo_num_stack[i][0] != '+' and rdo_num_stack[i][0] != '-'  and rdo_num_stack[i] != "") {
                 rdo_num_stack[i] = "+" + rdo_num_stack[i];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
         }
         if (rdo_num_stack[i] == "") {
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
         }
     }
    
     div_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "/") {
                 result = to_string(stof(rdo_num_stack[i-1]) / stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto div_loop;
             }
     }
    
     mul_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "*") {
                 result = to_string(stof(rdo_num_stack[i-1]) * stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto mul_loop;
             }
    
    
     }
    
    
     minus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '-' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
    
             goto minus_loop;
    
         }
    
     } 
    
     plus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '+' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=2;
             goto plus_loop;
    
         }
    
     }
    
     opp_count = 0;
    
     for (i = 0; i < rdo_num_stack.size();i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
    
             opp_count++;
    
         }
    
     }
    
     if (opp_count > 0) {
    
         for (i = depth; i < depth+diff;i++) {
             if (rdo_num_stack[i] == "(" and rdo_num_stack[i+2] == ")") {
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
    
             }
         }
    
     }
    
     expr = "";
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
     }
    
     expr = "";
     bcount = 0;
     depth = 0;
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
         if (rdo_num_stack[i] == "(") {
             bcount++;
             depth = i;
         }
     }
    
     result = rdo_num_stack[depth+1];
    
     rdo_num_stack.clear();
     if (opp_count > 0)
         return rdo_eval(expr);
     else
         expr = to_string(stoi(result));
         return expr;
    

    }

    int main() { int i;

     cout << rdo_eval("(10 + (20 * - (5 + 9)))") << endl << endl;
    
     return 0;
    

    }

Four-function expression evaluator

It understands +, -, /, *, brackets and the order of operations. I haven't put a modulus operator in the evaluator because I'm going to make a function for modulus instead.

(10 + (20 * - (5 + 9)))

I'd just like to know whether there are any ways I can improve my expression evaluator and whether there are any complicated expressions that don't evaluate correctly.

Also, is there a better way than using the time command on OSX to find out how fast it evaluates because the time command only does to 3 decimal places so it's not accurate enough?

(10 + (20 * - (14)))
  1. It first does the deepest brackets.
(10 + (20 * -14))
  1. Then, since there's a minus it multiplies the result of the brackets by -1.
(10 + (-280))
  1. Then it does the multiply in the brackets.
(-270)
  1. Then it does the addition with the 10 and the -280.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <functional>

using namespace std;

vector<string> rdo_num_stack;
int opp_count = 0;

bool rdo_ws(char c) {
    if (c != ' ')
        return 0;
    else
        return 1;
}

char rdo_expr_item_type(char c) {

    switch(c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '.':
            c = 'n';
            break;
        case '+':
        case '-':
        case '*':
        case '/':
            c = 'o';
            break;
        case '(':
        case ')':
            c = 'b';
            break;
    }

    return c;

}

string rdo_opp_to_string(char opp) {

    string o = "";

    switch(opp) {
        case '+':
            o = "+";
            break;
        case '-':
            o = "-";
            break;
        case '/':
            o = "/";
            break;
        case '*':
            o = "*";
            break;
        case '(':
            o = "(";
            break;
        case ')':
            o = ")";
            break;
    }

    return o;

}

bool rdo_is_num(string is_num) {
    if (is_num == "+" or
        is_num == "-" or
        is_num == "/" or
        is_num == "*" or
        is_num == "(" or
        is_num == ")") {
        return 0;
    }
    return 1;
}

void rdo_count_opp(bool to_count_or_not) {
    if (to_count_or_not == 1)
        opp_count++;
}

string rdo_eval(string expr) {

    string result;
    string num_holder = "";
    string temp_result = "";
    string num1 = "";
    string num2 = "";
    int n2 = 0;
    int i;
    int iter;
    int bcount = 0;
    int depth = 0;
    int current_depth = 0;
    int diff = 0;
    int diff2 = 0;
    int current_b = 0;
    int minus_count = 0;
    int minus_start = 0;
    int plus_count = 0;
    int plus_start = 0;
    bool found_end = 0;
    bool got_diff = 0;
    bool to_inverse = 0;
    bool do_calc = 0;

    for (i = 0; i < expr.length();i++) {

        if (!rdo_ws(expr[i])) {
            if (rdo_expr_item_type(expr[i]) == 'n' or rdo_expr_item_type(expr[i]) == 'o' or rdo_expr_item_type(expr[i]) == 'b') {

                if (rdo_expr_item_type(expr[i]) == 'n') {

                    num_holder += expr[i];

                } else if (rdo_expr_item_type(expr[i]) == 'o') {

                    if (num_holder != "") {

                        rdo_num_stack.push_back(num_holder);
                        num_holder = "";

                    }

                    rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));

                } else {

                    if (num_holder != "") {

                        rdo_num_stack.push_back(num_holder);
                        num_holder = "";

                    }

                    rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
                    bcount++;

                }
            
            } else {
                cout << "Invalid character in expression" << endl;
                exit(0);
            }

            if (i == expr.length()-1 and num_holder != "") {

                rdo_num_stack.push_back(num_holder);
                num_holder = "";

            }

        }

    }

    if (bcount % 2 != 0) {
        cout << "Extra / Missing parens." << endl;
        exit(0);
    } else {
        bcount /= 2;
    }

    for (i = 0; i < rdo_num_stack.size();i++) {
        if (rdo_num_stack[i] == "(") {
            current_b++;
            
        }
        if (current_b == bcount and !found_end) {
            if (i == 1)
                depth = 0;
            else
                depth = i;
            found_end = 1;
        }
        if (rdo_num_stack[i] == ")" and found_end and !got_diff) {
            diff = i - depth;
            got_diff = 1;
        }
    }


    for (i = depth; i < depth+diff; i++) {

        if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
            if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "-") {
                rdo_count_opp(0);
            } else if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "+") {
                rdo_count_opp(0);
            } else {
                rdo_count_opp(1);
            }
        }
    
    }


    for (i = depth; i <= depth+diff;i++) {

        if (rdo_num_stack[i] == "+" and rdo_num_stack[i+1] == "-") {

            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff -= 1;
        }
        if (rdo_num_stack[i] == "-" and rdo_num_stack[i+1] == "+") {

            rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
            diff -= 1;
        }
    }
        
    for (i = depth; i <= depth+diff;i++) {
        if (rdo_num_stack[i] == "-") {

            minus_count++;

            if (minus_start == 0) {
                minus_start = i;
            }
            
        }
        if (rdo_num_stack[i] != "-") {

            if (minus_count != 0 and minus_count % 2 == 0) {
                
                for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                if (rdo_num_stack[minus_start+minus_count] != "" and rdo_num_stack[minus_start+minus_count][0] != '+') {
                rdo_num_stack[minus_start+minus_count] = "+" + rdo_num_stack[minus_start+minus_count];
                }
                minus_start = 0;
                minus_count = 0;

            } else if (minus_count != 0 and minus_count % 2 != 0) {
                
                for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                rdo_num_stack[minus_start+minus_count] = "-" + rdo_num_stack[minus_start+minus_count];
                minus_start = 0;
                minus_count = 0;

            }
        }
    }

    for (i = depth; i <= depth+diff;i++) {
        if (rdo_num_stack[i] == "+") {

            plus_count++;

            if (plus_start == 0) {
                plus_start = i;
            }
            
        }
        if (rdo_num_stack[i] != "+") {
            for (iter = plus_start;iter < plus_start+plus_count;iter++) {
                    rdo_num_stack[iter] = "";
                }
                if (rdo_num_stack[plus_start+plus_count] != "" and rdo_num_stack[plus_start+plus_count][0] != '(') {
                rdo_num_stack[plus_start+plus_count] = "+" + rdo_num_stack[plus_start+plus_count];
                }

                plus_start = 0;
                plus_count = 0;
        }
    }

    for (i = depth+diff;i >= depth;i--) {
        if (i - 1 >= depth) {
            if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] != "(" and rdo_num_stack[i][0] != '+' and rdo_num_stack[i][0] != '-'  and rdo_num_stack[i] != "") {
                rdo_num_stack[i] = "+" + rdo_num_stack[i];
            }
            if (rdo_num_stack[i] == "/" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
            }
            if (rdo_num_stack[i] == "/" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
            }
            if (rdo_num_stack[i] == "*" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
            }
            if (rdo_num_stack[i] == "*" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
            }
        }
        if (rdo_num_stack[i] == "") {
            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=1;
        }
    }

    div_loop:for (i = depth+diff;i >= depth;i--) {
            
            if (rdo_num_stack[i] == "/") {
                result = to_string(stof(rdo_num_stack[i-1]) / stof(rdo_num_stack[i+1]));
                if (result[0] != '+' and result[0] != '-') {
                    result = "+" + result;
                }
                rdo_num_stack[i-1] = result;
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                diff -= 2;

                goto div_loop;
            }
    }

    mul_loop:for (i = depth+diff;i >= depth;i--) {
            
            if (rdo_num_stack[i] == "*") {
                result = to_string(stof(rdo_num_stack[i-1]) * stof(rdo_num_stack[i+1]));
                if (result[0] != '+' and result[0] != '-') {
                    result = "+" + result;
                }
                rdo_num_stack[i-1] = result;
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                diff -= 2;

                goto mul_loop;
            }

            
    }
  

    minus_loop:for (i = depth; i <= depth+diff;i++) {
        
        if (rdo_num_stack[i][0] == '-' and rdo_num_stack[i-1] != "(") {
            
            result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
            if (result[0] != '+' and result[0] != '-') {
                result = "+" + result;
            }
            rdo_num_stack[i-1] = result;
            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=1;
            
            goto minus_loop;

        }

    } 

    plus_loop:for (i = depth; i <= depth+diff;i++) {
        
        if (rdo_num_stack[i][0] == '+' and rdo_num_stack[i-1] != "(") {
            
            result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
            if (result[0] != '+' and result[0] != '-') {
                result = "+" + result;
            }
            rdo_num_stack[i-1] = result;

            rdo_num_stack.erase(rdo_num_stack.begin()+i);
            diff-=2;
            goto plus_loop;

        }

    }
 
    opp_count = 0;

    for (i = 0; i < rdo_num_stack.size();i++) {
        
        if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {

            opp_count++;

        }

    }

    if (opp_count > 0) {

        for (i = depth; i < depth+diff;i++) {
            if (rdo_num_stack[i] == "(" and rdo_num_stack[i+2] == ")") {
                rdo_num_stack.erase(rdo_num_stack.begin()+i);
                rdo_num_stack.erase(rdo_num_stack.begin()+i+1);

            }
        }

    }

    expr = "";

    for (i = 0; i < rdo_num_stack.size();i++) {
        expr += rdo_num_stack[i];
    }

    expr = "";
    bcount = 0;
    depth = 0;
    for (i = 0; i < rdo_num_stack.size();i++) {
        expr += rdo_num_stack[i];
        if (rdo_num_stack[i] == "(") {
            bcount++;
            depth = i;
        }
    }
    
    result = rdo_num_stack[depth+1];

    rdo_num_stack.clear();
    if (opp_count > 0)
        return rdo_eval(expr);
    else
        expr = to_string(stoi(result));
        return expr;
}

int main() {
    int i;


    cout << rdo_eval("(10 + (20 * - (5 + 9)))") << endl << endl;

    return 0;
}
Source Link
Francis
  • 547
  • 6
  • 10

Can you rate my C++ Expression Evaluator out of 10?

I've been making an interpreter for my own programming language that I've been working on as a hobby. I made an expression evaluator that can evaluate simple mathematical expressions.

It understands, +, -, /, *, brackets and the order of operations. I haven't put a modulus operator in the evaluator because I'm going to make a function for modulus instead.

I works in all of the tests I've tried. But I'd appreciate of anyone knows of any complicated expressions that it fails to evaluate.

It also understands that a positive number of minuses is that same as a plus.

It evaluates expressions like this:

(10 + (20 * - (5 + 9)))

and produce the correct output of, -270.

I'd just like to know whether there are any ways I can improve my expression evaluator and whether there are any complicated expressions that don't evaluate correctly. Also, is there a better way than using the time command on OSX to find out how fast it evaluates because the time command only does to 3 decimal places so it's not accurate enough.

My expression evaluator evaluates the above expression like this:

(10 + (20 * - (14)))
  1. It first does the deepest brackets.

    (10 + (20 * -14))

  2. Then, since there's a minus it multiplies the result of the brackets by -1.

    (10 + (-280))

  3. Then it does the multiply in the brackets.

    (-270)

  4. Then it does the addition with the 10 and the -280.

    #include #include #include #include #include #include #include #include #include

    using namespace std;

    vector rdo_num_stack; int opp_count = 0;

    bool rdo_ws(char c) { if (c != ' ') return 0; else return 1; }

    char rdo_expr_item_type(char c) {

     switch(c) {
         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         case '.':
             c = 'n';
             break;
         case '+':
         case '-':
         case '*':
         case '/':
             c = 'o';
             break;
         case '(':
         case ')':
             c = 'b';
             break;
     }
    
     return c;
    

    }

    string rdo_opp_to_string(char opp) {

     string o = "";
    
     switch(opp) {
         case '+':
             o = "+";
             break;
         case '-':
             o = "-";
             break;
         case '/':
             o = "/";
             break;
         case '*':
             o = "*";
             break;
         case '(':
             o = "(";
             break;
         case ')':
             o = ")";
             break;
     }
    
     return o;
    

    }

    bool rdo_is_num(string is_num) { if (is_num == "+" or is_num == "-" or is_num == "/" or is_num == "*" or is_num == "(" or is_num == ")") { return 0; } return 1; }

    void rdo_count_opp(bool to_count_or_not) { if (to_count_or_not == 1) opp_count++; }

    string rdo_eval(string expr) {

     string result;
     string num_holder = "";
     string temp_result = "";
     string num1 = "";
     string num2 = "";
     int n2 = 0;
     int i;
     int iter;
     int bcount = 0;
     int depth = 0;
     int current_depth = 0;
     int diff = 0;
     int diff2 = 0;
     int current_b = 0;
     int minus_count = 0;
     int minus_start = 0;
     int plus_count = 0;
     int plus_start = 0;
     bool found_end = 0;
     bool got_diff = 0;
     bool to_inverse = 0;
     bool do_calc = 0;
    
     for (i = 0; i < expr.length();i++) {
    
         if (!rdo_ws(expr[i])) {
             if (rdo_expr_item_type(expr[i]) == 'n' or rdo_expr_item_type(expr[i]) == 'o' or rdo_expr_item_type(expr[i]) == 'b') {
    
                 if (rdo_expr_item_type(expr[i]) == 'n') {
    
                     num_holder += expr[i];
    
                 } else if (rdo_expr_item_type(expr[i]) == 'o') {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
    
                 } else {
    
                     if (num_holder != "") {
    
                         rdo_num_stack.push_back(num_holder);
                         num_holder = "";
    
                     }
    
                     rdo_num_stack.push_back(rdo_opp_to_string(expr[i]));
                     bcount++;
    
                 }
    
             } else {
                 cout << "Invalid character in expression" << endl;
                 exit(0);
             }
    
             if (i == expr.length()-1 and num_holder != "") {
    
                 rdo_num_stack.push_back(num_holder);
                 num_holder = "";
    
             }
    
         }
    
     }
    
     if (bcount % 2 != 0) {
         cout << "Extra / Missing parens." << endl;
         exit(0);
     } else {
         bcount /= 2;
     }
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         if (rdo_num_stack[i] == "(") {
             current_b++;
    
         }
         if (current_b == bcount and !found_end) {
             if (i == 1)
                 depth = 0;
             else
                 depth = i;
             found_end = 1;
         }
         if (rdo_num_stack[i] == ")" and found_end and !got_diff) {
             diff = i - depth;
             got_diff = 1;
         }
     }
    
    
     for (i = depth; i < depth+diff; i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "-") {
                 rdo_count_opp(0);
             } else if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] == "+") {
                 rdo_count_opp(0);
             } else {
                 rdo_count_opp(1);
             }
         }
    
     }
    
    
     for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i] == "+" and rdo_num_stack[i+1] == "-") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff -= 1;
         }
         if (rdo_num_stack[i] == "-" and rdo_num_stack[i+1] == "+") {
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
             diff -= 1;
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "-") {
    
             minus_count++;
    
             if (minus_start == 0) {
                 minus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "-") {
    
             if (minus_count != 0 and minus_count % 2 == 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[minus_start+minus_count] != "" and rdo_num_stack[minus_start+minus_count][0] != '+') {
                 rdo_num_stack[minus_start+minus_count] = "+" + rdo_num_stack[minus_start+minus_count];
                 }
                 minus_start = 0;
                 minus_count = 0;
    
             } else if (minus_count != 0 and minus_count % 2 != 0) {
    
                 for (iter = minus_start;iter < minus_start+minus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 rdo_num_stack[minus_start+minus_count] = "-" + rdo_num_stack[minus_start+minus_count];
                 minus_start = 0;
                 minus_count = 0;
    
             }
         }
     }
    
     for (i = depth; i <= depth+diff;i++) {
         if (rdo_num_stack[i] == "+") {
    
             plus_count++;
    
             if (plus_start == 0) {
                 plus_start = i;
             }
    
         }
         if (rdo_num_stack[i] != "+") {
             for (iter = plus_start;iter < plus_start+plus_count;iter++) {
                     rdo_num_stack[iter] = "";
                 }
                 if (rdo_num_stack[plus_start+plus_count] != "" and rdo_num_stack[plus_start+plus_count][0] != '(') {
                 rdo_num_stack[plus_start+plus_count] = "+" + rdo_num_stack[plus_start+plus_count];
                 }
    
                 plus_start = 0;
                 plus_count = 0;
         }
     }
    
     for (i = depth+diff;i >= depth;i--) {
         if (i - 1 >= depth) {
             if (rdo_num_stack[i-1] == "(" and rdo_num_stack[i] != "(" and rdo_num_stack[i][0] != '+' and rdo_num_stack[i][0] != '-'  and rdo_num_stack[i] != "") {
                 rdo_num_stack[i] = "+" + rdo_num_stack[i];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "/" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i-1][0] != '+' and rdo_num_stack[i-1][0] != '-') {
                 rdo_num_stack[i-1] = "+" + rdo_num_stack[i-1];
             }
             if (rdo_num_stack[i] == "*" and rdo_num_stack[i+1][0] != '+' and rdo_num_stack[i+1][0] != '-') {
                 rdo_num_stack[i+1] = "+" + rdo_num_stack[i+1];
             }
         }
         if (rdo_num_stack[i] == "") {
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
         }
     }
    
     div_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "/") {
                 result = to_string(stof(rdo_num_stack[i-1]) / stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto div_loop;
             }
     }
    
     mul_loop:for (i = depth+diff;i >= depth;i--) {
    
             if (rdo_num_stack[i] == "*") {
                 result = to_string(stof(rdo_num_stack[i-1]) * stof(rdo_num_stack[i+1]));
                 if (result[0] != '+' and result[0] != '-') {
                     result = "+" + result;
                 }
                 rdo_num_stack[i-1] = result;
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 diff -= 2;
    
                 goto mul_loop;
             }
    
    
     }
    
    
     minus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '-' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=1;
    
             goto minus_loop;
    
         }
    
     } 
    
     plus_loop:for (i = depth; i <= depth+diff;i++) {
    
         if (rdo_num_stack[i][0] == '+' and rdo_num_stack[i-1] != "(") {
    
             result = to_string(stof(rdo_num_stack[i]) + stof(rdo_num_stack[i-1]));
             if (result[0] != '+' and result[0] != '-') {
                 result = "+" + result;
             }
             rdo_num_stack[i-1] = result;
    
             rdo_num_stack.erase(rdo_num_stack.begin()+i);
             diff-=2;
             goto plus_loop;
    
         }
    
     }
    
     opp_count = 0;
    
     for (i = 0; i < rdo_num_stack.size();i++) {
    
         if (rdo_num_stack[i] == "+" or rdo_num_stack[i] == "-" or rdo_num_stack[i] == "*" or rdo_num_stack[i] == "/") {
    
             opp_count++;
    
         }
    
     }
    
     if (opp_count > 0) {
    
         for (i = depth; i < depth+diff;i++) {
             if (rdo_num_stack[i] == "(" and rdo_num_stack[i+2] == ")") {
                 rdo_num_stack.erase(rdo_num_stack.begin()+i);
                 rdo_num_stack.erase(rdo_num_stack.begin()+i+1);
    
             }
         }
    
     }
    
     expr = "";
    
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
     }
    
     expr = "";
     bcount = 0;
     depth = 0;
     for (i = 0; i < rdo_num_stack.size();i++) {
         expr += rdo_num_stack[i];
         if (rdo_num_stack[i] == "(") {
             bcount++;
             depth = i;
         }
     }
    
     result = rdo_num_stack[depth+1];
    
     rdo_num_stack.clear();
     if (opp_count > 0)
         return rdo_eval(expr);
     else
         expr = to_string(stoi(result));
         return expr;
    

    }

    int main() { int i;

     cout << rdo_eval("(10 + (20 * - (5 + 9)))") << endl << endl;
    
     return 0;
    

    }