Open In App

All ways to add parenthesis for evaluation

Improve
Improve
Like Article
Like
Save
Share
Report

Given a string that represents an expression constituting numbers and binary operator +, – and * only. We need to parenthesize the expression in all possible way and return all evaluated values.

Input : expr = “3-2-1”
Output : {0, 2}
((3-2)-1) = 0
(3-(2-1)) = 2
Input : expr = "5*4-3*2"
Output : {-10, 10, 14, 10, 34}
(5*(4-(3*2))) = -10
(5*((4-3)*2)) = 10
((5*4)-(3*2)) = 14
((5*(4-3))*2) = 10
(((5*4)-3)*2) = 34

We can solve this problem by parenthesizing all possible valid substring of the expression and then evaluating them, but as we can see that it will involve solving lots of repeating subproblem, to save ourselves we can follow a dynamic programming approach. We store the result for each substring in a map and if string in recursion is already solved, we return result from map instead of solving that again. Below code runs a loop in the string and if at any instant, character is operator then we divide the input from there, recursively solve each part and then combine the result in all possible ways. See the use of c_str() function, this function converts the C++ string into C char array, this function is used in below code because atoi() function expects a character array as an argument not the string. It converts character array to number. 

A

C++




//  C++ program to output all possible values of
// an expression by parenthesizing it.
#include <bits/stdc++.h>
using namespace std;
 
//  method checks, character is operator or not
bool isOperator(char op)
{
    return (op == '+' || op == '-' || op == '*');
}
 
//  Utility recursive method to get all possible
// result of input string
vector<int> possibleResultUtil(string input,
            map< string, vector<int> > memo)
{
    //  If already calculated, then return from memo
    if (memo.find(input) != memo.end())
        return memo[input];
 
    vector<int> res;
    for (int i = 0; i < input.size(); i++)
    {
        if (isOperator(input[i]))
        {
            // If character is operator then split and
            // calculate recursively
            vector<int> resPre =
              possibleResultUtil(input.substr(0, i), memo);
            vector<int> resSuf =
              possibleResultUtil(input.substr(i + 1), memo);
 
            //  Combine all possible combination
            for (int j = 0; j < resPre.size(); j++)
            {
                for (int k = 0; k < resSuf.size(); k++)
                {
                    if (input[i] == '+')
                        res.push_back(resPre[j] + resSuf[k]);
                    else if (input[i] == '-')
                        res.push_back(resPre[j] - resSuf[k]);
                    else if (input[i] == '*')
                        res.push_back(resPre[j] * resSuf[k]);
                }
            }
        }
    }
 
    // if input contains only number then save that
    // into res vector
    if (res.size() == 0)
        res.push_back(atoi(input.c_str()));
 
    // Store in memo so that input string is not
    // processed repeatedly
    memo[input] = res;
    return res;
}
 
//  method to return all possible output
// from input expression
vector<int> possibleResult(string input)
{
    map< string, vector<int> > memo;
    return possibleResultUtil(input, memo);
}
 
//  Driver code to test above methods
int main()
{
    string input = "5*4-3*2";
    vector<int> res = possibleResult(input);
 
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << " ";
    return 0;
}


Java




import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
 
public class PossibleExpressionValues {
 
    // Method to check if a character is an operator
    private static boolean isOperator(char op) {
        return (op == '+' || op == '-' || op == '*');
    }
 
    // Utility recursive method to get all possible results of an input string
    private static ArrayList<Integer> possibleResultUtil(String input, Map<String, ArrayList<Integer>> memo) {
        // If already calculated, then return from memo
        if (memo.containsKey(input)) {
            return memo.get(input);
        }
 
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = 0; i < input.length(); i++) {
            if (isOperator(input.charAt(i))) {
                // If the character is an operator, then split and calculate recursively
                ArrayList<Integer> resPre = possibleResultUtil(input.substring(0, i), memo);
                ArrayList<Integer> resSuf = possibleResultUtil(input.substring(i + 1), memo);
 
                // Combine all possible combinations
                for (int j = 0; j < resPre.size(); j++) {
                    for (int k = 0; k < resSuf.size(); k++) {
                        if (input.charAt(i) == '+')
                            res.add(resPre.get(j) + resSuf.get(k));
                        else if (input.charAt(i) == '-')
                            res.add(resPre.get(j) - resSuf.get(k));
                        else if (input.charAt(i) == '*')
                            res.add(resPre.get(j) * resSuf.get(k));
                    }
                }
            }
        }
 
        // If the input contains only a number, then save it into the result vector
        if (res.isEmpty())
            res.add(Integer.parseInt(input));
 
        // Store in memo so that the input string is not processed repeatedly
        memo.put(input, res);
        return res;
    }
 
    // Method to return all possible outputs from an input expression
    private static ArrayList<Integer> possibleResult(String input) {
        Map<String, ArrayList<Integer>> memo = new HashMap<>();
        return possibleResultUtil(input, memo);
    }
 
    // Driver code to test the above methods
    public static void main(String[] args) {
        String input = "5*4-3*2";
        ArrayList<Integer> res = possibleResult(input);
 
        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i) + " ");
        }
    }
}


Python3




# Python program to output all possible values of
# an expression by parenthesizing it.
 
# method checks, character is operator or not
def isOperator(op):
    return (op == '+' or op == '-' or op == '*')
 
# Utility recursive method to get all possible
# result of input string
def possibleResultUtil(input, memo):
    # If already calculated, then return from memo
    if input in memo:
        return memo[input]
 
    res = []
    for i in range(len(input)):
        if isOperator(input[i]):
            # If character is operator then split and
            # calculate recursively
            resPre = possibleResultUtil(input[:i], memo)
            resSuf = possibleResultUtil(input[i+1:], memo)
 
            # Combine all possible combination
            for j in range(len(resPre)):
                for k in range(len(resSuf)):
                    if input[i] == '+':
                        res.append(resPre[j] + resSuf[k])
                    elif input[i] == '-':
                        res.append(resPre[j] - resSuf[k])
                    elif input[i] == '*':
                        res.append(resPre[j] * resSuf[k])
 
    # if input contains only number then save that
    # into res list
    if len(res) == 0:
        res.append(int(input))
 
    # Store in memo so that input string is not
    # processed repeatedly
    memo[input] = res
    return res
 
# method to return all possible output
# from input expression
def possibleResult(input):
    memo = {}
    return possibleResultUtil(input, memo)
 
# Driver code to test above methods
if __name__ == '__main__':
    input = "5*4-3*2"
    res = possibleResult(input)
 
    for i in range(len(res)):
        print(res[i], end=' ')


C#




using System;
using System.Collections.Generic;
 
class Program
{
    //  method checks, character is operator or not
    static bool isOperator(char op)
    {
        return (op == '+' || op == '-' || op == '*');
    }
 
    //  Utility recursive method to get all possible
    // result of input string
    static List<int> possibleResultUtil(string input,
            Dictionary<string, List<int>> memo)
    {
        //  If already calculated, then return from memo
        if (memo.ContainsKey(input))
            return memo[input];
 
        List<int> res = new List<int>();
        for (int i = 0; i < input.Length; i++)
        {
            if (isOperator(input[i]))
            {
                // If character is operator then split and
                // calculate recursively
                List<int> resPre =
                  possibleResultUtil(input.Substring(0, i), memo);
                List<int> resSuf =
                  possibleResultUtil(input.Substring(i + 1), memo);
 
                //  Combine all possible combination
                for (int j = 0; j < resPre.Count; j++)
                {
                    for (int k = 0; k < resSuf.Count; k++)
                    {
                        if (input[i] == '+')
                            res.Add(resPre[j] + resSuf[k]);
                        else if (input[i] == '-')
                            res.Add(resPre[j] - resSuf[k]);
                        else if (input[i] == '*')
                            res.Add(resPre[j] * resSuf[k]);
                    }
                }
            }
        }
 
        // if input contains only number then save that
        // into res vector
        if (res.Count == 0)
            res.Add(int.Parse(input));
 
        // Store in memo so that input string is not
        // processed repeatedly
        memo[input] = res;
        return res;
    }
 
    //  method to return all possible output
    // from input expression
    static List<int> possibleResult(string input)
    {
        Dictionary<string, List<int>> memo = new Dictionary<string, List<int>>();
        return possibleResultUtil(input, memo);
    }
 
    //  Driver code to test above methods
    static void Main(string[] args)
    {
        string input = "5*4-3*2";
        List<int> res = possibleResult(input);
 
        for (int i = 0; i < res.Count; i++)
            Console.Write(res[i] + " ");
 
        Console.ReadLine();
    }
}
// ksam24000


Javascript




// Function to check if a character is an operator
function isOperator(op) {
    return (op === '+' || op === '-' || op === '*');
}
 
// Utility recursive function to get all possible results of the input string
function possibleResultUtil(input, memo) {
    // If already calculated, then return from memo
    if (memo[input] !== undefined) {
        return memo[input];
    }
 
    let res = [];
 
    for (let i = 0; i < input.length; i++) {
        if (isOperator(input[i])) {
            // If character is an operator, then split and calculate recursively
            const resPre = possibleResultUtil(input.substring(0, i), memo);
            const resSuf = possibleResultUtil(input.substring(i + 1), memo);
 
            // Combine all possible combinations
            for (let j = 0; j < resPre.length; j++) {
                for (let k = 0; k < resSuf.length; k++) {
                    if (input[i] === '+') {
                        res.push(resPre[j] + resSuf[k]);
                    } else if (input[i] === '-') {
                        res.push(resPre[j] - resSuf[k]);
                    } else if (input[i] === '*') {
                        res.push(resPre[j] * resSuf[k]);
                    }
                }
            }
        }
    }
 
    // If input contains only a number, then save it into the result vector
    if (res.length === 0) {
        res.push(parseInt(input));
    }
 
    // Store in memo so that the input string is not processed repeatedly
    memo[input] = res;
    return res;
}
 
// Function to return all possible outputs from the input expression
function possibleResult(input) {
    const memo = {};
    return possibleResultUtil(input, memo);
}
 
// Driver code to test the above functions
const input = "5*4-3*2";
const res = possibleResult(input);
 
// Print the results
for (let i = 0; i < res.length; i++) {
    console.log(res[i]);
}


Output:

-10 10 14 10 34 



Last Updated : 13 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads