Home > Blockchain >  Evaluating math expressions fails with "-" symbol
Evaluating math expressions fails with "-" symbol

Time:06-06

I'm creating a program to evaluate math expressions. It takes two inputs: a integer and a string of space-seperated math expressions. It should return the index of the expression that matches the integer input.

Sample input:

20
(2 2) (10 10) (3*5*6)

Sample output:

index 1

It seems my logic fails when using the subtraction operator so I've focused on the "subtraction evaluation" section of my code. All other operators seem to succeed. I'm trying to figure if what I'm missing. Any help is appreciated - Thank you.

An example input that fails would be:

-8
(2-2-2-2-2-2)

Here is my code:

#include <iostream>
#include <algorithm>
#include <regex>
using namespace std;

int main() {
    
 int input;
 string w;
    
 cin >> input;
    
 // ws ignore spaces or "whitespace"
 getline(cin >> ws, w);
    
 int w_len = w.length();
    
 // count total expressions in string
 int exp = 1;
 for (int i = 0; i <= w_len; i  ) {
     if (isspace(w[i])) {
         exp  ;
     }
 }
    
 // create array to hold expressions
 string w_arr[exp];
    
 // populate s_arr elements with the expressions
 int wcount = 0;
 for (int i = 0; i <= w_len; i  ) {
     if (w[i] == ' ') {
         wcount  ;
         i  ; 
     }
     w_arr[wcount]  = w[i];
 }
    
 int w_size = sizeof(w_arr) / sizeof(w_arr[1]);
    
 string s;
 int index = -1;
 
 // start of the evaluation loop
 for (int k = 0; k < w_size; k  ) {
 index  ;
 s = w_arr[k];
    
    
 s.erase(remove(s.begin(),s.end(),'('), s.end());
 s.erase(remove(s.begin(),s.end(),')'), s.end());
    
    // count total punctuation
    int count = 0;
    for (size_t i = 0; i < s.length(); i  ) {
        if (ispunct(s[i])) {
            count  ;
        }
    }
    
    // add spaces around operators
    s = regex_replace(s, regex("\\ "), "   ");
    s = regex_replace(s, regex("\\*"), " * ");
    s = regex_replace(s, regex("\\/"), " / ");
    s = regex_replace(s, regex("\\-"), " - ");
    
    int count2 = 0;
    int size = count   count   1;
    string z[size];
    
    // create array z[] from input string
    for (size_t i = 0; i < s.length(); i  ) {
        if (s[i] == ' ') {
            count2  ;
            i  ;
        }
        z[count2]  = s[i];
    }
    
    // multiplication evaluation
    string res;
    mulStart:
    for (int j = 0; j <= size; j  ) {
        if (z[j] == "*") {
            int mul1 = stoi(z[j-1]);
            int mul2 = stoi(z[j 1]);
            int mul = mul1 * mul2;
            res = to_string(mul);
            
            // overwrite expression with result
            z[j-1] = res;
            for (int i = j; i<=size-3; i  ) {
                z[i] = z[i 2];
            }
            
            // replace end of array with blanks
            for (int i = size-2; i<size; i  ) {
                z[i] = " ";
            }
        }
    }
    
    // check for other mul operators
    size = sizeof(z) / sizeof(z[0]);
    int mulCount = 0;
    for (int i = 0; i <= size; i  ) {
        if (z[i] == "*") {
            mulCount  ;
        }
    }
    if (mulCount > 0) {
        goto mulStart;
    }
    
    // division evaluation
    divStart:
    for (int j = 0; j <= size; j  ) {
        if (z[j] == "/") {
            int div1 = stoi(z[j-1]);
            int div2 = stoi(z[j 1]);
            int div = div1 / div2;
            res = to_string(div);
            
            // overwrite expression with result
            z[j-1] = res;
            for (int i = j; i<=size-3; i  ) {
                z[i] = z[i 2];
            }
            
            // replace end of array with blanks
            for (int i = size-2; i<size; i  ) {
                z[i] = " ";
            }
        }
    }
    
    // check for other div operators
    size = sizeof(z) / sizeof(z[0]);
    int divCount = 0;
    for (int i = 0; i <= size; i  ) {
        if (z[i] == "/") {
            divCount  ;
        }
    }
    if (divCount > 0) {
        goto divStart;
    }
    
    // addition evaluation
    addStart:
    for (int j = 0; j <= size; j  ) {
        if (z[j] == " ") {
            int add1 = stoi(z[j-1]);
            int add2 = stoi(z[j 1]);
            int add = add1   add2;
            res = to_string(add);
            
            // overwrite expression with result
            z[j-1] = res;
            for (int i = j; i<=size-3; i  ) {
                z[i] = z[i 2];
            }
            
            
            // replace end of array with blanks
            for (int i = size-2; i<size; i  ) {
                z[i] = " ";
            }
        }
    }
    
    // check for other add operators
    size = sizeof(z) / sizeof(z[0]);
    int addCount = 0;
    for (int i = 0; i <= size; i  ) {
        if (z[i] == " ") {
            addCount  ;
        }
    }
    if (addCount > 0) {
        goto addStart;
    }
    
    // subtraction evaluation
    subStart:
    for (int j = 0; j <= size; j  ) {
        if (z[j] == "-") {
            int sub1 = stoi(z[j-1]);
            int sub2 = stoi(z[j 1]);
            int sub = sub1 - sub2;
            res = to_string(sub);
            
            // overwrite expression with result
            z[j-1] = res;
            for (int i = j; i<=size-3; i  ) {
                z[i] = z[i 2];
            }
            
            // replace end of array with blanks
            for (int i = size-2; i<size; i  ) {
                z[i] = " ";
            }
        }
    }
    
    // check for other sub operators
    size = sizeof(z) / sizeof(z[0]);
    int subCount = 0;
    for (int i = 0; i <= size; i  ) {
        if (z[i] == "-") {
            subCount  ;
        }
    }
    if (subCount > 0) {
        goto subStart;
    }
     
    
    // print out index result
    if (stoi(z[0]) == input) {
        cout << "index " << index << endl;
        break;
    }
    
    // print "none" otherwise
    if (k == w_size - 1) {
        cout << "none" << endl;
    }
    
 }
 
    return 0;
}

CodePudding user response:

"// check for other sub operators" This should have given you a clue. You already iterate over all the input but somehow there seem to be "-" left over after and you need to do it again. But you can compute "-" out of order.

The problem is that you advance the index j even when you find a -. By eliminating the one - the next - takes the place of the one you removed. And then you skip that.

Lets take you example, I numbered the - to show how they move as you loop:

"2-2-2-2-2-2" becomes:

"2" "-"1 "2" "-"2 "2" "-"3 "2" "-"4 "2" "-"5 "2"
 ^

"2" "-"1 "2" "-"2 "2" "-"3 "2" "-"4 "2" "-"5 "2"
     ^

"0" "-"2 "2" "-"3 "2" "-"4 "2" "-"5 "2"
          ^

"0" "-"2 "2" "-"3 "2" "-"4 "2" "-"5 "2"
              ^ 

"0" "-"2 "0" "-"4 "2" "-"5 "2"
                   ^ 

"0" "-"2 "0" "-"4 "2" "-"5 "2"
                       ^ 

"0" "-"2 "0" "-"4 "0"

and then you goto subStart.

The same problem should be there with /.

Getting worse you are doing * before /. So what will happen to 4 * 9 / 2 * 3? Same for and -: 1 2 - 3 4.

  • Related