繁体   English   中英

使用 c++ 将中缀转换为后缀

[英]Converting infix to postfix using c++

我正在尝试将中缀转换为后缀。 我认为我的代码没有错,但显然是因为它不起作用。 我不知道要更改什么才能使我的代码正常工作。

(之前有点用,现在不行了)

我遵循了 geeksforgeeks 的这段代码: https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/但我更改了其中的一些代码,因为网站上的代码也是错误的。

对不起,如果我的解释有点不清楚。 这是我的代码:

#include <bits/stdc++.h>
using namespace std;

int checks(char c)
{
    if (c=='^')
    {
        return 1;
    }
    else if (c=='+' || c=='-')
    {
        return 2;
    }
    else if (c=='*' || c=='/')
    {
        return 3;
    } else
    {
        return -1;
    }
}

int main()
{
    stack <char> stack;
    string result, input;
    cout<<"Enter your equation: ";
    cin>> input;
    
    for (int i=0; i<input.length(); i+=1)
    {
        if (input[i]=='(')
        {
            stack.push(input[i]);
        } else if (isalnum(input[i]))
        {
            result+=input[i];
        } else if (input[i]==')')
        {
            while(!stack.empty() && stack.top() != '(') 
            { 
                char c = stack.top(); 
                stack.pop(); 
                result += c; 
            } 
            if(stack.top() == '(') 
            { 
                char c = stack.top(); 
                stack.pop(); 
            } 
        } else
        {
            if (checks(stack.top()) >= checks(input[i]))
            {
                result+=stack.top();
                stack.pop();
            } else
            {
                stack.push(input[i]);
            }
        }
    }
    
    while(!stack.empty())
    {
        if (stack.top()=='(' || stack.top()==')')
        {
            stack.pop();
        } else
        {
            result+=stack.top();
            stack.pop();
        }
    }
    
    cout<<"Result is: ";
    cout<<result<<endl;
    return 0;
}

您可以跳过实际创建树结构的步骤,但必须记住中缀表示法可以用树表示,而波兰表示法可以用堆栈表示。 (a+b)*(c+d)*是最顶层的节点,下一级是两个+abcd 它是一棵对称树,因为所有操作都是可交换的。 但是((a+b)*(c+d))/3是不对称的,最顶层节点/不可交换。 -也会出现类似的问题,因为它也不是可交换的。

例如,每一步的可能选项可以是(不是严格的算法,而是说明一个人应该如何行动,irt 需要防御格式错误的语法)

  1. Token是一个“id”。它是树节点的当前级别,向右扫描
  2. 令牌是一种交换操作。 它是节点的上层。 下一个令牌将是同一级别的节点
  3. Token 是一个不可交换的操作,/ 或 -。 它是节点的上层。 下一个标记与当前标记和操作之间的节点有关。
  4. */优先于+- ,因此它们是较低级别的节点。 例如a+b*c ,首先我们的树是+: [a,b] ,然后是+:[a,*:[b,c]]
  5. 令牌是( 。扫描字符串并计算所有大括号,直到找到匹配) 例如,每个(增加计数器,每个)减少。 如果计数器为 0,则找到匹配项。如果在到达终端字符时得到正数或负数,则手头有语法错误。 () 内的所有内容都是较低级别的节点。 完成所有上层后扫描它。

要真正扫描字符串,需要一台 state 机器在循环中运行,完成的标志是没有令牌要处理。 可以递归也可以不递归。

如果你避免创建树,你必须 go 沿着字符串本身的标记上下移动,找到最顶层的节点,将其推入堆栈,然后是左右节点(按此顺序),推入堆栈等。弹出堆栈时,后进先出,操作将按正确的顺序出现。

Paul Floyd 正确地提醒,运算符优先级可用于对顺序节点或令牌进行排序,尽管在std::stack中这样做是不可能的,因为它只有 push 和 pop 操作并且不可能重新排序,所以你必须存储单独或扫描并重新扫描字符串以将适当的元素推入。

(注意,当你使用一些像 TI 那样的 RPN 计算器时,操作堆栈充当 LILO 堆栈,而当从语法树转换为 RPN 时,它是 LIFO)

您的中缀表达式是否使用标准数学优先级? 如果是这样,与简单的从左到右评估相比,这将显着改变事情。

您需要将程序分成两个阶段。 在第一阶段,您将解析表达式并构建堆栈。 在第二个中,您将遍历堆栈并评估结果。

正如我所说,解析将由优先级决定。 如果您使用标准优先级,那么通常的方法(您可以在 Stroustrup 的“The C++ Programming Language”中阅读)是使用递归下降。 然后,您将对括号、术语、因子、一元运算符和文字有不同的优先级。 对这些使用枚举,而不是像 1、2、3 这样的幻数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM