Not logged in. Log in with GitHub. About Websheets.

List of all available Websheets


Viewing cpp/recursion/evaluate by daveagp@gmail.com. You have unsaved changes. Log in above to create, edit, preview and publish Websheets.
PropertyValue
Description
html markup
shown to student
 
Define a function <code>evaluate()</code> that evaluates
a mathematical expression (a string) consisting of
integers, +, *, and parentheses.
<p>
For example,
<ul>
<li><tt>evaluate("11+23");</tt> returns 34
<li><tt>evaluate("(1+1)*5");</tt> returns 10
</ul>
By definition, it must use
 recursion to evaluate two halves of the expression and
combine them. The string manipulation and logic are filled in, but
you need to add two recursive calls and a base case.
Public permissions remove
Engine
Template / Reference solution
 
#include <iostream>
#include <cstdlib>
// cstdlib is for atoi
using namespace std;
int evaluate(string expression) {
   // here -1 means 'not found yet'
   int plusPos = -1; // position of last '+' outside of parentheses
   int timesPos = -1; // position of last '*' outside of parentheses
   // scan expression, looking for operators outside of parentheses
   int level = 0; // current nesting depth
   for (int i=0; i<expression.length(); i++) {
      char ch = expression[i];
      // look for operator
      if (ch=='+' && level==0) plusPos = i;
      if (ch=='*' && level==0) timesPos = i;
  
      // count level of parentheses
      if (ch=='(') level++;
      if (ch==')') level--;
   }
   
   // recurse on lowest-precedence operator
   if (plusPos != -1) {
      // break down, e.g. "3*4+5*6" => "3*4" and "5*6"
      string exprLeft = expression.substr(0, plusPos);
      string exprRight = expression.substr(plusPos+1);
      int valueLeft = evaluate(exprLeft);
      int valueRight = evaluate(exprRight);
      return valueLeft + valueRight;
   }
   else if (timesPos != -1) {
      // break down, e.g. "(3+4)*(5+6)" => "(3+4)" and "(5+6)"
      string exprLeft = expression.substr(0, timesPos);
      string exprRight = expression.substr(timesPos+1);
\[
      int valueLeft = evaluate(exprLeft);
      int valueRight = evaluate(exprRight);
      return valueLeft * valueRight;
]\
   }
   else if (expression[0]=='(') {
      // everything was in a matched pair of parentheses
      // break down, e.g. "(3*4)" => "3*4"
      return evaluate(expression.substr(1, expression.length()-1));
   }
   else {
      // base case: just a number like "12". convert expression to int.
      // don't make any recursive calls
      // 1. convert C++ string to C string
      const char* num_cstr = expression.c_str();
      // 2. convert C string to integer and return it
      return \[atoi]\(num_cstr);
   }
}
int main() {
   string expr;
   cin >> expr;
   cout << evaluate(expr);
}
C++ test suite
json list of stdin/args tests
e.g. [{"stdin":"hi", "args":["4", "5"]},
{"stdin":"noargs"}]

to just run once with no input use [{}]
 
[
   {"stdin": "11+19"},
   {"stdin": "(1+1)*5"},
   {"stdin": "2*2+3*3"},
   {"stdin": "(2*(1+6*2+2)+6*6+2*2*(1+2+6))+6*2*2"},
   {"stdin": "103+456*789"}
]
Solution visibility remove


Optional properties:

Note: problems are open-source by default (see 'Public permissions'). Assumed license for open problems is Creative Commons 4.0 Attribution-ShareAlike unless specified in 'Remarks'.