【问题标题】:How do I convert an infix expression to a postfix expression and I am not able to get the expected output?如何将中缀表达式转换为后缀表达式并且我无法获得预期的输出?
【发布时间】:2020-12-23 22:04:12
【问题描述】:

我正在尝试编写一个 C++ 程序来将中缀表达式转换为前缀和后缀。我哪里做错了?

如何更改代码以删除最后一个表单(后缀)的括号? 感谢您的帮助!

输入:

a*(b-c+d)/e

输出:

abc-d+*e/
/*a+-bcde

约束/假设:

  1. 表达平衡。
  2. 唯一使用的运算符是+-*/
  3. 左括号和右括号 - ( ) - 用于影响操作的优先级。
  4. +- 具有相同的优先级,小于 */*/ 的优先级也相同。
  5. 在两个优先级相等的运算符中,优先考虑左边的那个。
  6. 所有操作数都是一位数字/字符。
#include <cstring>
#include <ctype.h>
#include <iostream>
#include <stack>
#include <string>
using namespace std;

int precedence(char ch) {
    if (ch == '+') {
        return (1);
    } else if (ch == '-') {
        return (1);
    } else {
        return (2);
    }
}

void preProcess(stack<string> &preS, char op) {
    string val2 = preS.top();
    preS.pop();
    string val1 = preS.top();
    preS.pop();
    string prev;
    prev = op + val1 + val2;
    preS.push(prev);
}

void postProcess(stack<string> &postS, char op) {
    string val2 = postS.top();
    postS.pop();
    string val1 = postS.top();
    postS.pop();
    string postv;
    postv = val1 + val2 + op;
    postS.push(postv);
}

void prefixPostfixEvaluation(string expr) {
    stack<string> preS;
    stack<string> postS;
    stack<char> opS;
    for (int i = 0; i < expr.length(); ++i) {
        char ch = expr.at(i);
        if (ch == '(') {
            opS.push(ch);
        } else if ((ch <= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') ||
                   (ch <= 'A' && ch >= 'Z')) {
            string s;
            s = ch;
            preS.push(s);
            postS.push(s);
        } else if (ch == ')') {
            while (opS.top() != '(') {
                char op = opS.top();

                preProcess(preS, op);
                postProcess(postS, op);
                opS.pop();
            }
            opS.pop();
        } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
            while (opS.size() > 0 && precedence(ch) <= precedence(opS.top()) &&
                   opS.top() != '(') {
                char op = opS.top();

                preProcess(preS, op);
                postProcess(postS, op);
                opS.pop();
            }
            opS.push(ch);
        }
    }
    while (opS.size() > 0) {
        char op = opS.top();
        opS.pop();
        if (op == '(' || op == ')') {
            continue;
        } else {
            preProcess(preS, op);
            postProcess(postS, op);
        }
    }
    cout << preS.top() << endl;
    cout << postS.top();
}

int main() {
    string expr;
    getline(cin, expr);
    prefixPostfixEvaluation(expr);
}

【问题讨论】:

  • 乍一看,(ch&lt;='0'&amp;&amp;ch&lt;='9')||(ch&gt;='a'&amp;&amp;ch&lt;='z')||(ch&lt;='A'&amp;&amp;ch&gt;='Z') 的条件看起来很奇怪,尤其是第一对和最后一对由() 复合。
  • 你的缩进有多艺术!
  • 你能详细说明一下吗
  • (ch&lt;='0'&amp;&amp;ch&lt;='9') 等价于ch&lt;='0'。如果'A' 小于'Z'(ch&lt;='A'&amp;&amp;ch&gt;='Z') 将永远不会变为真。
  • 听起来您可能需要学习如何使用调试器来单步调试您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programsDebugging Guide

标签: c++ stack queue infix-notation postfix-operator


【解决方案1】:

您检查字符是否为操作数的条件是错误的。而不是:

(ch &lt;= '0' &amp;&amp; ch &lt;= '9') || (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &lt;= 'A' &amp;&amp; ch &gt;= 'Z')

应该是

(ch &gt;= '0' &amp;&amp; ch &lt;= '9') || (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z')

更好的方法是在条件语句中直接使用isalnum(ch)(您已经包含ctype 标头)。

完整(更正)代码可以在here找到。

注意:最好包含诸如 &lt;cctype&gt; 之类的标头的 C++ 变体,而不是 &lt;ctype.h&gt;。此外,当包含&lt;string&gt; 时,不需要包含&lt;cstring&gt;。另外,请通过此线程:Why is “using namespace std;” considered bad practice?

您希望后缀版本出现在第 1 行,前缀版本出现在第 2 行。但是在您以相反顺序打印的代码中,如果顺序对您很重要,请更改它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2021-06-28
    • 2017-10-02
    • 2013-11-12
    相关资源
    最近更新 更多