在C ++中使用递归将表达式括起来以获得最小结果

时间:2019-09-30 07:41:40

标签: c++ algorithm recursion dynamic-programming parentheses

所以我写了这段代码,以最小化和最大化使用递归的表达式。该代码成功运行并给出表达式的最大值。但是,它没有给出最小值。 我要去哪里错了。两个变量minummaxum分别存储INT_MAX和INT_MIN。

我正在做的是产生所有可能性,并且只要结果变得最小,而不是已经存储在最小值中,我们就会对其进行更新。

int parenthesis(string &S, int i, int j, int &minum, int &maxum)
{
    if(i>j)
        return 0;
    if(i==j)
        return S[i]-48;

    int k, rightr, leftr, res;
    for(k=i+1;k<j;k+=2)
    {
        // evaluate the left expression
        leftr = parenthesis(S, i, k-1, minum, maxum);
        // evaluate the right expression
        rightr = parenthesis(S, k+1, j, minum, maxum);
        if(S[k]=='/')
            res = leftr / rightr;
        else if(S[k]=='*')
            res = leftr * rightr;
        else if(S[k]=='-')
            res = leftr - rightr;
        else 
            res = leftr + rightr;

        // update the minum and the maxum variable
        if(res>maxum)
            maxum = res;
        if(res<minum)
            minum = res;

    }
    return res;
}

int main()
{
    string S;
    int N, i, j, k;
    cin>>S;
    int minum=INT_MAX, maxum=INT_MIN;
    j = S.size()-1;
    parenthesis(S, 0, j, minum, maxum);

    cout<<minum<<" "<<maxum;
    return 0;
}

`

我要去哪里错了。为什么代码给出了正确的最大值却没有给出最小值。例如,对于1+2*3+4*5,预期输出为Minimum value : 27, Maximum value : 105,但我将其输出为Minimum value : 3, Maximum value : 105

注意:仅允许输入一位数字。

编辑:即使有人可以告诉我原因,为什么不起作用,也可以作为答案

2 个答案:

答案 0 :(得分:2)

请考虑以下解决方案,它探讨了所有可能性。基本不变式是,由于我们的代数有限(DMAS),因此只有一个对{max value,min value}是重要的候选者。贪婪的选择可以用交换参数来争论(即使是负数,除法除0外,也可以作为特殊情况处理)。

pair<int, int> Maximize(string S, int i, int j)
{
    if(i>j)
        return {0, 0};
    if(i==j)
        return {S[i]-48, S[i]-48};
    int maxim = INT_MIN;
    int minim = INT_MAX;

    int k, res;
    for(k=i+1;k<j;k+=2)
    {
        // evaluate the left expression
        auto leftr = Maximize(S, i, k-1);
        // evaluate the right expression
        auto rightr = Maximize(S, k+1, j);
        for (auto sign1 = 0; sign1 < 2; ++sign1) {
            for (auto sign2 = 0; sign2 < 2; ++sign2) {
                int l = sign1? leftr.first: leftr.second;
                int r = sign2? rightr.first: rightr.second;
                if(S[k]=='/')
                    res = l / r;
                else if(S[k]=='*')
                    res = l * r;
                else if(S[k]=='-')
                    res = l - r;
                else 
                    res = l + r;
                // update the minim and the maxim variable
                if(res>maxim)
                    maxim = res;
                if(res<minim)
                    minim = res;
            }
        }

    }
    return {maxim, minim};
}

int main()
{
    string S;
    int j;
    // cin>>S;
    S = "1+2*3+4*5";
    j = S.size()-1;
    auto res = Maximize(S, 0, j);
    cout << res.first << " " << res.second << "\n";

    return 0;
} 

答案 1 :(得分:-2)

您的算法已损坏。问题是您正在评估任何子表达式的最小值。例如,当k = 3时,求值“ 1 + 2”,并确定其值为3-小于任何其他子表达式的值,并且小于总表达式的最小可能值。

可悲的是,您的方法甚至无法发挥最大作用。给定1/2 + 1,整个表达式的最大可能值为1 == 1/2 + 1,但最大可能的子表达式为3(2 + 1)。我不知道该如何解决。