当前位置: 首页 > 知识库问答 >
问题:

计算中缀表达式而不将其转换为后缀[duplicate]

章昱
2023-03-14

我试图在1次传递中评估一个内插表达式,而不将其转换为后缀,但它没有为某些表达式提供正确的输出。例如:3-5*10/5 10 , (45 5)-5*(100/10) 5

是否有人能在cpp中为这个问题提供适当的解决方案。

链接到上一个问题:如何使用堆栈在一次扫描中计算中缀表达式?

请不要将其标记为重复,因为我已经尝试了上述给定线程中回答的算法,但没有效果。

#include<bits/stdc++.h>

int isoperand(char x)
{
    if(x == '+' || x=='-'|| x=='*' || x=='/' || x==')' || x=='(')
        return 0;
    return 1;
}

int Pre(char x)
{
    if(x == '+' || x == '-')
        return 1;
    if(x == '*' || x == '/')
        return 3;
    return 0;
}

int infixevaluation(std::string exp)
{
    std::stack<int> s1; //Operand Stack
    std::stack<char> s2; //Operator Stack
    int i,x,y,z,key;
    i=0;
    while(exp[i]!='\0')
    {

        if(isoperand(exp[i]))
        {
            key = exp[i]-'0';
            s1.push(key);
            i++;
        }
        else if(!isoperand(exp[i]) && s2.empty())
            s2.push(exp[i++]);
        else if(!isoperand(exp[i]) && !s2.empty())
        {
            if(Pre(exp[i])>Pre(s2.top()) && exp[i]!=')')
                s2.push(exp[i++]);
            else if(exp[i]==')' && s2.top() == '(')
            {
                s2.pop();
                i++;
            }
            else if(exp[i]=='(')
                s2.push(exp[i++]);
            else
            {
                x = s1.top();
                s1.pop();
                y = s2.top();
                s2.pop();
                z = s1.top();
                s1.pop();
                if(y == '+')
                    s1.push(z+x);
                else if(y == '-')
                    s1.push(z-x);
                else if(y == '*')
                    s1.push(x*z);
                else if(y == '/')
                    s1.push(z/x);
            } 
        }
    }
    while(!s2.empty())
    {
        x = s1.top();
        s1.pop();
        y = s2.top();
        s2.pop();
        z = s1.top();
        s1.pop();
        if(y == '+')
            s1.push(x+z);
        else if(y == '-')
            s1.push(z-x);
        else if(y == '*')
            s1.push(x*z);
        else if(y == '/')
            s1.push(z/x);
    }
    return s1.top();
}

int main(int argc, char const *argv[])
{
    std::string s;
    getline(std::cin,s);
    std::cout<<infixevaluation(s)<<std::endl;
    return 0;
}

共有1个答案

裴翰学
2023-03-14

您的代码只能处理一位数的操作数,并且它没有检查格式错误的输入,因此当您有一个多位数的操作数时,它会运行异常。

对于前者,最简单的修复方法就是在看到数字时扫描数字——将if(isoperand(exp[i])子句更改为:

    if (isdigit(exp[i])) {
        int value = 0;
        while (isdigit(exp[i]))
            value = value * 10 + exp[i++] - '0';
        s1.push(value);
    } else ...

对于错误检查,您应该执行以下操作

  • 检查空格和其他无效字符,并拒绝或跳过它们
  • 跟踪最后匹配的标记是操作数还是运算符,并为两个连续的操作数或除)以外的两个连续运算符提供错误

 类似资料:
  • 本文向大家介绍将中缀转换为后缀表达式,包括了将中缀转换为后缀表达式的使用技巧和注意事项,需要的朋友参考一下 前缀表达式是人类可读和可解的。我们可以轻松地区分算子的顺序,也可以在计算数学表达式时先使用括号将其求解。计算机无法轻松地区分运算符和括号,这就是为什么需要后缀转换的原因。 要将中缀表达式转换为后缀表达式,我们将使用堆栈数据结构。通过从左到右扫描infix表达式,当我们得到任何操作数时,只需将

  • 本文向大家介绍将中缀转换为前缀表达式,包括了将中缀转换为前缀表达式的使用技巧和注意事项,需要的朋友参考一下 要通过计算机求解表达式,我们可以将其转换为后缀形式或前缀形式。在这里,我们将看到中缀表达式如何转换为前缀形式。 首先,中缀表达式反转。注意,对于反转,圆括号也将反转。 例如:表达式:A + B *(C-D) 反转后的表达式为:)D – C(* B + A 因此我们需要将左括号转换为右括号,反

  • 本文向大家介绍中缀表达式转后缀表达式相关面试题,主要包含被问及中缀表达式转后缀表达式时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 对于中缀表达式,遇到操作数直接将其输出,如果遇到操作符和左括号全部压入栈中,若遇到右括号则将栈中元素全部弹出,直到遇到左括号为止。压栈过程中,若遇到其它操作符,从栈中弹出元素直到遇到更低优先级的操作符为止。

  • 我的讲师给了我一个任务,让我创建一个程序,使用堆栈将表达式和中缀转换为后缀。我制作了堆栈类和一些函数来读取中缀表达式。 但是这个函数,叫做,它负责使用堆栈将数组inFix中的inFix表达式转换为数组postFix中的postfix表达式,并没有做它应该做的事情...你们能帮帮我告诉我哪里做错了吗? 下面是从中缀转换为后缀的函数的代码,是我需要帮助修复的代码: 注意:convertToPostfi

  • 这是一个理论上的问题: 我必须计算一个表达式,我已经从中缀转换到后缀。后缀保存在中,因为我希望避免使用。这样我就知道数字之间的除法在哪里,我可以按“正确”的顺序访问它。 它看起来是这样的: 现在我想用两个堆栈: null 如果我到达一个运算符,并且数量计数至少为2,我将执行该操作并将其推到目标堆栈上。到达原始堆栈的末尾(现在是空的),我会把所有的东西都传递给它,然后从头开始,直到只剩下结果。 我现

  • 我没有得到正确的输出为这个程序得到abcde-*给输入在主 这个程序是将表达式从中缀转换为后缀这里是算法 算法1。从左到右扫描中缀表达式。 如果扫描的字符是操作数,则将其输出。 否则, ......3.1如果扫描的运算符的优先级大于堆栈中运算符的优先级(或者堆栈是空的),则推送它。...... 3.2否则,从堆栈中弹出操作符,直到被扫描操作符的优先级小于-等于位于堆栈顶部的操作符的优先级。将扫描的