📜  加括号进行求值的所有方式

📅  最后修改于: 2021-09-22 10:06:33             🧑  作者: 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

我们可以通过将表达式的所有可能的有效子串加括号然后对它们求值来解决这个问题,但正如我们所见,这将涉及解决许多重复的子问题,为了节省我们自己,我们可以遵循动态规划方法。
我们将每个子字符串的结果存储在一个映射中,如果递归中的字符串已经被求解,我们从映射返回结果而不是再次求解。
下面的代码在字符串运行一个循环,如果在任何时刻,字符是运算符,那么我们从那里分割输入,递归求解每个部分,然后以所有可能的方式组合结果。
参见 c_str()函数的使用,该函数将 C++字符串转换为 C 字符数组,在下面的代码中使用该函数是因为 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 

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程