Different Ways to Add Parentheses : An Optimised Approach

Problem Explanation

You are given a string expression that consists of numbers and operators (+-*). The goal is to compute all possible results from different ways to group the numbers and operators. This means that you can parenthesize the expression in various ways, and you need to evaluate each of these groupings to find all unique results.

For example:

  • For the expression "2-1-1", you can group it as:
    • ((2-1)-1) = 0
    • (2-(1-1)) = 2
    Thus, the output would be [0, 2].
  • For the expression "2*3-4*5", you can group it in several ways, leading to results like -34-14-10, and 10.

Constraints

  • The length of the expression is between 1 and 20.
  • The expression consists of digits and the operators +-, and *.
  • All integer values in the input expression are in the range [0, 99].

Approach to solve the problem

To generate all possible results from a string expression of numbers and operators in C++, a recursive approach is often used. The algorithm involves splitting the expression at each operator, recursively calculating the results of the left and right sub-expressions, and then combining these results based on the operator. This process continues until all combinations are explored, yielding all possible outcomes. ### Steps to Code a Recursive Expression Evaluator in C++

  1. Define the Function:
    • Create a function that takes a string expression as input and returns a vector of integers containing all possible results.
  2. Base Case:
    • If the expression is a number (i.e., contains no operators), convert it to an integer and return it in a vector.
  3. Recursive Case:
    • Loop through each character in the string:
      • If the character is an operator (+-*/):
        • Split the expression into left and right sub-expressions.
        • Recursively call the function on both sub-expressions to get their results.
        • Combine the results based on the operator and store them.
  4. Combine Results:
    • Depending on the operator, perform the appropriate arithmetic operation on the results from the left and right sub-expressions.
  5. Return Results:
    • After processing all operators, return the vector containing all possible results.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

std::vector<int> diffWaysToCompute(std::string expression) {
    std::vector<int> results;

    // Base case: if the expression is a number
    if (isdigit(expression[0])) {
        results.push_back(std::stoi(expression));
        return results;
    }

    // Recursive case: split the expression at each operator
    for (int i = 0; i < expression.size(); i++) {
        char op = expression[i];
        if (op == '+' || op == '-' || op == '*') {
            // Split the expression into left and right parts
            std::string left = expression.substr(0, i);
            std::string right = expression.substr(i + 1);

            // Recursively compute results for left and right parts
            std::vector<int> leftResults = diffWaysToCompute(left);
            std::vector<int> rightResults = diffWaysToCompute(right);

            // Combine results based on the operator
            for (int l : leftResults) {
                for (int r : rightResults) {
                    if (op == '+') {
                        results.push_back(l + r);
                    } else if (op == '-') {
                        results.push_back(l - r);
                    } else if (op == '*') {
                        results.push_back(l * r);
                    }
                }
            }
        }
    }
    return results;
}

int main() {
    std::string expression = "2*3-4*5";
    std::vector<int> results = diffWaysToCompute(expression);

    std::cout << "All possible results: ";
    for (int result : results) {
        std::cout << result << " ";
    }
    return 0;
}

Expression: "2*3-4*5"

We will break down the computation into sub-expressions and show how the results are combined.

Dry Run Table

StepExpressionOperatorLeft PartRight PartLeft ResultsRight ResultsCombined Results
12*3-4*5*23-4*5[2]TBDTBD
23-4*5-34*5[3]TBDTBD
34*5*45[4][5][20]
43-4*5-320[3][20][3-20 = -17]
52*3-4*5*2-17[2][-17][2*-17 = -34]
62*3-4*5-2*34*5[-14][20][-14]
72*3*23[2][3][6]
82*3-4*5-620[6][20][6-20 = -14]
92*3-4*5*23[2][3][6]
102*3-4*5-620[6][20][6-20 = -14]
112*3-4*5*23[2][3][6]
122*3-4*5-620[6][20][6-20 = -14]
132*3-4*5*23[2][3][6]
142*3-4*5-620[6][20][6-20 = -14]
152*3-4*5*23[2][3][6]
162*3-4*5-620[6][20][6-20 = -14]
172*3-4*5*23[2][3][6]
182*3-4*5-620[6][20]

Leave a Reply

Your email address will not be published. Required fields are marked *