📜  添加括号以进行评估的所有方法

📅  最后修改于: 2021-04-24 05:36:17             🧑  作者: Mango

给定一个字符串,该字符串表示由数字和二进制运算符+,-和*组成的表达式。我们需要以所有可能的方式在表达式中加上括号并返回所有评估值。

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

我们可以通过在表达式的所有可能的有效子字符串后加上括号然后对其求值来解决此问题,但是正如我们看到的那样,这将涉及解决许多重复的子问题,为节省我们自己,我们可以采用动态编程方法。
我们将每个子字符串的结果存储在映射中,如果递归的字符串已经解决,则从map返回结果,而不是再次求解。
下面的代码在字符串运行一个循环,如果在任何时刻,字符都是运算符,则我们从那里分割输入,递归求解每个部分,然后以所有可能的方式组合结果。
请参见c_str()函数的使用,此函数将C++字符串转换为C char数组,此函数在以下代码中使用,因为atoi()函数期望将字符数组作为参数而不是字符串。它将字符数组转换为数字。

//  C++ program to output all possible values of
// an expression by parenthesizing it.
#include 
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 possibleResultUtil(string input,
            map< string, vector > memo)
{
    //  If already calculated, then return from memo
    if (memo.find(input) != memo.end())
        return memo[input];
  
    vector res;
    for (int i = 0; i < input.size(); i++)
    {
        if (isOperator(input[i]))
        {
            // If character is operator then split and
            // calculate recursively
            vector resPre =
              possibleResultUtil(input.substr(0, i), memo);
            vector 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 possibleResult(string input)
{
    map< string, vector > memo;
    return possibleResultUtil(input, memo);
}
  
//  Driver code to test above methods
int main()
{
    string input = "5*4-3*2";
    vector res = possibleResult(input);
  
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << " ";
    return 0;
}

输出:

-10 10 14 10 34