infix prefix postfix的区别

转载:http://blog.csdn.net/chhj0103121429/article/details/40925555

对于给定的一个的表达式: a * b + c * d. 我们称之为infix表达式. 这是我们看得比较习惯的方式.

但是编译器这样看不好, 不像人可以自动辨别优先级. 所以出现了 prefix 和 postfix 两种表达式, 其中prefix是操作符在前, postfix是操作符在后.


手工转换非常简单, 只要给所有运算添上括号, 然后将括号中的操作符移动到括号外, 最后移除括号就能得出 postfix 或者 prefix 表达式.

如转换为prefix: a * b + c * d → ((a * b) + (c * d)) → + ( * (a b) * (c d)) → + * a b * c d

转换为postfix: a * b + c * d → ((a * b) + (c * d)) → ((a b) * (c d) * ) + → a b * c d * +


程序转换:

转prefix:

1.两个堆栈, 一个存放操作数, 一个存放运算符

2.由于要转换为prefix, 运算符在操作数前, 所以扫描从中缀表达式的右往左扫描.

3.如果是操作数, 则直接压进操作数栈中

4.如果是运算符, 分以下情况:

    a. 运算符堆栈为空, 或者运算符栈顶元素为')', 则直接将运算符压进栈

    b. 运算符如果是'(', 则将运算符栈中的元素都压进去操作数栈中并将其弹出运算符栈, 直到遇到')'为止

    c. 运算操作符是'+' '-' '*' '/' 之一的时候, 将其与运算符栈顶元素作比较,如果优先级相同, 或者栈顶的优先级较小, 则将运算符压入栈中. 

       否则, 将栈顶元素弹出并压入操作数栈中, 然后继续比较栈顶, 直到运算符被压入栈.

5.扫描完一遍后, 将运算符堆栈剩余的元素都压入操作数栈中.

6.将操作数栈从栈顶到栈底输出就是prefix.


转postfix:

1.一个存放结果的输出队列, 一个存放运算符的堆栈

2.由于要转换为postfix, 运算符在操作数后, 所以扫描从中缀表达式的左往右扫描.

3.如果是操作数, 则直接压进输出队列中

4.如果是运算符, 分以下情况:

    a. 运算符堆栈为空, 或者运算符栈顶元素为'(', 则直接将运算符压进栈

    b. 运算符如果是')', 则将运算符栈中的元素都压进去输出队列中并将其弹出运算符栈, 直到遇到'('为止

    c. 运算操作符是'+' '-' '*' '/' 之一的时候, 将其与运算符栈顶元素作比较,如果栈顶的优先级较小, 则将运算符压入栈中. 

       否则, 将栈顶元素弹出并压入输出队列中, 然后继续比较栈顶, 直到运算符被压入栈.

5.扫描完一遍后, 将运算符堆栈剩余的元素都压入输出队列中.

6.将队列输出就是postfix.


计算prefix表达式的值:

1. 用一个堆栈存放中间结果.

2.右往左扫描前缀表达式.

   a. 如果遇到操作数, 直接压进栈

   b. 遇到运算符, 将栈顶元素弹出置于操作数, 再弹出一个栈顶元素置于操作数. 然后进行运算:"左操作数 运算符 右操作数". 生成结果压入栈中

3.扫描完后, 将栈中的结果输出便是答案


计算postfix表达式的值:

1. 用一个堆栈存放中间结果.

2.左往右扫描后缀表达式.

   a. 如果遇到操作数, 直接压进栈

   b. 遇到运算符, 将栈顶元素弹出置于操作数, 再弹出一个栈顶元素置于操作数. 然后进行运算:"左操作数 运算符 右操作数". 生成结果压入栈中

3.扫描完后, 将栈中的结果输出便是答案

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现中缀表达式转后缀表达式和前缀表达式的图形化界面,需要使用一些第三方库来实现界面设计和用户交互。下面以Qt为例,给出一个简单的实现过程: 1. 创建一个Qt项目并添加一个主窗口,用于显示图形界面。 2. 在主窗口上添加一些控件,如文本框、按钮等,用于输入中缀表达式、显示后缀表达式和前缀表达式等。 3. 在按钮的点击事件中编写代码,实现中缀表达式转后缀表达式和前缀表达式的功能。可以使用栈来实现转换过程。 4. 将转换后的后缀表达式和前缀表达式显示在相应的文本框中。 下面是一个简单的示例代码,用于实现中缀表达式转后缀表达式和前缀表达式的图形化界面: ```cpp #include <QMainWindow> #include <QLineEdit> #include <QPushButton> #include <QLabel> #include <QHBoxLayout> #include <QStack> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { // 创建控件 infixEdit = new QLineEdit(this); postfixLabel = new QLabel(this); prefixLabel = new QLabel(this); convertBtn = new QPushButton("转换", this); // 创建布局 QHBoxLayout *layout = new QHBoxLayout(); layout->addWidget(infixEdit); layout->addWidget(convertBtn); layout->addWidget(postfixLabel); layout->addWidget(prefixLabel); // 创建中缀表达式转后缀表达式和前缀表达式的连接 connect(convertBtn, &QPushButton::clicked, this, &MainWindow::convert); // 设置布局 QWidget *widget = new QWidget(this); widget->setLayout(layout); setCentralWidget(widget); } public slots: void convert() { QString infix = infixEdit->text(); QString postfix = infixToPostfix(infix); QString prefix = infixToPrefix(infix); postfixLabel->setText(postfix); prefixLabel->setText(prefix); } private: QLineEdit *infixEdit; QLabel *postfixLabel; QLabel *prefixLabel; QPushButton *convertBtn; QString infixToPostfix(const QString &infix) { QStack<QChar> stack; QString postfix; for (int i = 0; i < infix.length(); i++) { QChar ch = infix[i]; if (ch.isDigit() || ch.isLetter()) { postfix += ch; } else if (ch == '(') { stack.push(ch); } else if (ch == ')') { while (!stack.isEmpty() && stack.top() != '(') { postfix += stack.pop(); } if (!stack.isEmpty() && stack.top() == '(') { stack.pop(); } } else { while (!stack.isEmpty() && precedence(stack.top()) >= precedence(ch)) { postfix += stack.pop(); } stack.push(ch); } } while (!stack.isEmpty()) { postfix += stack.pop(); } return postfix; } QString infixToPrefix(const QString &infix) { QString reversed = reverse(infix); QString postfix = infixToPostfix(reversed); QString prefix = reverse(postfix); return prefix; } int precedence(QChar op) { if (op == '+' || op == '-') { return 1; } else if (op == '*' || op == '/') { return 2; } return 0; } QString reverse(const QString &str) { QString reversed; for (int i = str.length() - 1; i >= 0; i--) { reversed += str[i]; } return reversed; } }; ``` 在上面的代码中,我们创建了一个MainWindow类,并在其中添加了一个用于输入中缀表达式的文本框、一个用于显示后缀表达式的标签、一个用于显示前缀表达式的标签和一个用于转换的按钮。在按钮的点击事件中,我们调用了infixToPostfix()和infixToPrefix()函数,分别实现了中缀表达式转后缀表达式和前缀表达式的功能。其中,infixToPostfix()函数使用了栈来实现转换过程,infixToPrefix()函数则先将中缀表达式翻转,再调用infixToPostfix()函数,最后再将结果翻转回去得到前缀表达式。 这样,我们就实现了一个简单的中缀表达式转后缀表达式和前缀表达式的图形化界面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值