【问题标题】:Converting from Infix to Postfix using stacks (c++)使用堆栈从中缀转换为后缀 (c++)
【发布时间】:2015-09-13 18:27:03
【问题描述】:

我目前正在做一个项目,使用单链表形式的堆栈从后缀转换为中缀。我已经设法将ab+ 等表达式转换为(a+b),但是当表达式变得更长时,例如ab+cd*-。它不起作用。我正在考虑将先前转换的表达式推回堆栈,但是堆栈的类型是 char 并且表达式是字符串,当我尝试将其推回时它会抱怨。我应该把它做成一个模板吗?如果是,我该怎么做,或者还有其他方法可以解决这个问题。

这是我的代码:

#include "stack.h"

void convert(string expression){
    stack c;
    string post = " ";
    string rightop = "";
    string leftop = "";
    string op = "";

    for (int i = 0; i <= expression.length(); i++){
        c.push(expression[i]);
        c.print();
        if (expression[i] == '*' ||
            expression[i] == '+' ||
            expression[i] == '-' ||
            expression[i] == '/'){
            cout << c.top() << endl;
            leftop = c.top();
            cout << leftop << endl;

            c.pop();

            rightop = c.top();
            cout << rightop << endl;
            c.pop();
            op = c.top();
            cout << op << endl;
            //c.pop();
            post = "(" + leftop + " " + op + " " + rightop + ")";

            cout << post << endl;
        }
        //c.push(post);
    }
}


int main(){   
    string expression;
    cout << " Enter a Post Fix expression: ";    
    getline(cin, expression);    
    convert(expression);    
    return 0;
}

【问题讨论】:

  • 由于要将整个表达式转换为中缀表示法,因此您的堆栈必须能够保存整个表达式,而不仅仅是字符。也就是说,无论何时解析表达式,都必须将其压入堆栈。您可以一次将整个表达式推入一个字符,前提是您用括号将它们分隔,但是您会遇到计算左括号等的复杂情况

标签: c++ linked-list stack postfix-notation infix-notation


【解决方案1】:

原始代码缺少以下编译声明:

#include "stack"
#include "string"
#include "iostream"

using namespace std;

接下来,堆栈的类型应该是string,以便能够在其中存储完整的表达式。

您没有按正确顺序从堆栈中取出元素:首先是 op,接下来是 rightop,最后是 leftop

当前注释掉的最后一个 c.pop() 是从堆栈中删除第三个元素所必需的,但它必须循环内之后使用(再次注释掉) c.push(post);

expression 上的循环走得太远了:它应该是for (int i =0; i&lt;expression.length();i++)(注意&lt; 而不是&lt;=

完成后,让convert 函数将最后一个post 作为字符串返回给程序以给出预期结果就足够了。

正如您在此other question 中所问的,最好忽略输入字符串中的空格:您应该在for 之后立即添加if (isspace(expression[i])) continue;

通过所有这些修复,代码可能是:

#include <stack>
#include <string>
#include <iostream>
#include <cctypes>

using namespace std;

string convert(string expression){

    stack<string> c;

    string post =" ";
    string rightop="";
    string leftop="";
    string op ="";

    for (int i =0; i<expression.length();i++){
        if (isspace(expression[i])) continue;
        c.push(string(expression.c_str() + i, 1));
        //c.print();
        if(expression[i] == '*' ||
            expression[i] == '+' ||
            expression[i] == '-' ||
            expression[i] == '/'){
                cout<<c.top()<<endl;
                op=c.top();
                cout<<leftop<<endl;

                c.pop();


                rightop=c.top();
                cout<<rightop<<endl;
                c.pop();
                leftop=c.top();
                cout<<op<<endl;
                c.pop();
                post="(" + leftop + " " + op + " " + rightop + ")";

                cout<<post<<endl;
                c.push(post);
        }
    }
    return post;
}

int main(){

    string expression;
    cout<<" Enter a Post Fix expression: ";

    getline(cin,expression);

    string converted = convert(expression);

    cout << "Converted expression : " << converted << endl;

    return 0;
}

当给定ab+cd*-时,你会得到((a + b) - (c * d))

您只需注释掉转换方法中的所有痕迹;-)

【讨论】:

  • 您所说的包含在 .h 文件中,因为我不想让读者不知所措,所以没有显示该文件。我不能将堆栈作为类型字符串放置,因为它会抱怨我想把角色推到上面。 pop 在最后一个实例中不起作用,这就是我将其排除在外的原因。感谢您的回复,但您确实提到了我已经有答案的错误,并告诉我解决我作为练习提出的原始问题。
  • @KharlMccatty :我已经解决了你问题的最大部分 :-) 。我的代码编译并运行。我使用string(expression.c_str() + i, 1) 将字符转换为字符串,以便能够将其推入堆栈。最后一个pop 可以工作,前提是您使用c.push(post); 在循环内跟随它。我不知道你已经解决了这些问题。我列出它们只是为了解释我对原始代码的更改。无论如何,我刚刚重写了我的答案,因为这确实是不必要的粗鲁。我为此道歉,但很生气,因为我花了一些时间来编译代码:-(
【解决方案2】:

我觉得您的“堆栈”没有正确使用。例如如果将 ab+* 压入堆栈,您的变量将变为 leftop = +rightop = bop = a,为了转换后缀表达式,最简单的方法是创建二叉求值树来获得正确的运算符优先级

例如

你想要的ab+c*

     *
    / \
   +   c
  / \
 a   b 

然后递归地或不递归地评估树。每当运算符为 + 或 - 时,请在其周围使用括号,

【讨论】:

    猜你喜欢
    • 2015-09-12
    • 2012-09-22
    • 2013-11-08
    • 2013-03-28
    • 2015-04-19
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    相关资源
    最近更新 更多