使用链表堆栈的中缀到后缀转换器

Posted

技术标签:

【中文标题】使用链表堆栈的中缀到后缀转换器【英文标题】:Infix to Postfix converter using linked list stack 【发布时间】:2012-11-29 07:35:01 【问题描述】:

编写一个程序,该程序使用链表堆栈将中缀表示法的方程式转换为后缀表示法。程序的堆栈部分是它自己的类,在它自己的头文件中,并且实现正确(能够编译运行我教授提供的test main)。我目前正在研究将中缀字符串转换为继承类中的后缀字符串的实际函数。我有以下代码,我认为它在某处错误地完成了调车场算法,因为我得到了奇怪的输出。

template <class myType>
void infixToPostfix<myType>::convertToPostfix()

    linkedStack<char> newS; //creating a new char stack
    string output; //creating the postfix output string

    for(int i = 0; i < infx.length(); i++) //cycle through the entire string
    
        if (isgraph(infx[i])) //skip spaces
        
            if (isalpha(infx[i])) //if the char is a letter (caps or uncaps)
            
                output += infx[i]; //append it to output
            
            else
            
                if (newS.isEmptyStack()) newS.push(infx[i]);
                else if (precedence(infx[i], newS.top()) //check if the current char has higher precedence than the top of the stack, or if the stack is empty
                
                    newS.push(infx[i]); //push the current char onto the stack
                
                else if (infx[i] == ')') //check if the current char is a closing paren
                
                    for(;;)
                    
                        if (newS.isEmptyStack()) break;
                        if (newS.top() != '(') //check if the top of the stack isn't an open paren
                        
                            output += newS.top(); //append the top of the stack to the output
                            newS.pop(); //pop the top of the stack off
                        
                        else //the top of the stack is a (
                        
                            newS.pop(); //pop the ( off the stack
                            break; //break out of the for loop
                        
                    
                
                else //the current char doesn't have higher precedence than the top of the stack
                
                    output += newS.top(); //append to the top of the stack to output
                    newS.pop(); //pop off the top of the stack
                    newS.push(infx[i]); //put the current char onto the top of the stack
                
            
        
    

    while (!newS.isEmptyStack()) //not sure if this works, assuming we're at the end of the line at this point, and if there's anything on the stack we need to append it to the output
    
        output += newS.top();
        newS.pop();
    

    pfx = output; //setting pfx to the output (pfx is the class variable for the postfix output)


我显示后缀字符串的函数如下

template <class myType>
void infixToPostfix<myType>::showPostfix()

    cout << "Postfix Expression: " << pfx << endl;

我在运行程序时得到以下输出。

silverbox@silverbox-VirtualBox:~/Dropbox/CS202/ass13$ ./a.out testinput1.txt
Infix Expression: A + B - C
-ostfix Expression: AB+C
Infix Expression: A + B * C
*+stfix Expression: ABC
Infix Expression: A * B + C / D
/+stfix Expression: AB*CD
Infix Expression: (A + B) * C
*+(tfix Expression: AB)C
Infix Expression: A * (B + C) / D
/+(tfix Expression: A*BC)D
Infix Expression: (A + B) * (C - D)
-(+(fix Expression: AB)*CD)
Infix Expression: A * (B + C / D)
/+(tfix Expression: A*BCD)
Infix Expression: A + ((B + C) * (E - F) - G) / (H - I)
-(--(+( Expression: A+(BC)*EF)G)/HI)
silverbox@silverbox-VirtualBox:~/Dropbox/CS202/ass13$ 

老实说,我不明白为什么看起来像后缀表达式的奇数位会被推到我 cout 中的字符串上。任何提示/帮助?

编辑:在进行 ymett 建议的更改后,我的输出如下。我现在正试图找出我在尝试处理括号时出错的地方。

silverbox@silverbox-VirtualBox:~/Dropbox/CS202/ass13$ ./a.out testinput1.txt
Infix Expression: A + B - C
Postfix Expression: AB+C-
Infix Expression: A + B * C
Postfix Expression: ABC*+
Infix Expression: A * B + C / D
Postfix Expression: AB*CD/+
Infix Expression: (A + B) * C
Postfix Expression: AB)C*+(
Infix Expression: A * (B + C) / D
Postfix Expression: A*BC)D/+(
Infix Expression: (A + B) * (C - D)
Postfix Expression: AB)*CD)-(+(
Infix Expression: A * (B + C / D)
Postfix Expression: A*BCD)/+(
Infix Expression: A + ((B + C) * (E - F) - G) / (H - I)
Postfix Expression: A+(BC)*EF)G)/HI)-(--(+(
silverbox@silverbox-VirtualBox:~/Dropbox/CS202/ass13$ 

【问题讨论】:

不知道这是否是原因,但在if (precedence(infx[i], newS.top()) || newS.isEmptyStack()) 中,您应该真正检查空堆栈first。如果为空,则没有优先级! for(;;) 循环类似——当你进入它时,堆栈不是空的,但在第一次弹出之后它可能是空的。每一回合都需要检查。 @BoPersson 在检查优先级之前我自己添加了对 isEmptyStack() 的检查(并告诉它如果它是空的则只推入堆栈)以及添加对 isEmptyStack() 的检查如果堆栈为空,则 for 循环的顶部会中断。遗憾的是没有区别,但感谢您的建议。更新了原始帖子以显示所做的更改。 pfx 是在哪里定义的?输出字符串如何复制到 pfx 中?此外,if (infx[i] >= 65 && infx[i] @AdityaKumarPandey pfx 在我的头文件中被定义为 infixToPostfix 类的一部分。它被简单地定义为string pfx;。如有必要,我可以提供头文件/所有使用的功能,我只是不想在这里转储不必要的项目。输出被复制到提供代码底部的 pfx:pfx = output。关于if (infx[i] &gt;= 65 &amp;&amp; infx[i] &lt;= 122),你是对的。谢谢你的收获,我会解决的。 【参考方案1】:

您还没有显示infx 是如何填充的,但它似乎在末尾有一个回车符 (CR, '\r', 0x0d, 13)。

您的条件infx[i] != ' ' 应替换为检查任何空白字符的条件,即!isblank(infx[i])。更好的是,不要检查你不想要的字符,而是检查你想要的字符;如果您没有列表,请使用isgraph(infx[i])(任何具有可见表示的字符,即不是控制字符或空格)。

infx[i] &gt;= 65 &amp;&amp; infx[i] &lt;= 122 的条件也不好。首先,您应该使用字符文字而不是数字,即infx[i] &gt;= 'A' &amp;&amp; infx[i] &lt;= 'z'。其次,您在'Z''a' 之间包含了不是字母的字符,所以它应该是(infx[i] &gt;= 'A' &amp;&amp; infx[i] &lt;= 'Z') || (infx[i] &gt;= 'a' &amp;&amp; infx[i] &lt;= 'z')。此外,您假设字母在字符集中是连续的,这对于 ASCII 但并非对于所有字符集都是正确的(尽管也许我们不必担心这一点)。更好地使用语言给你的工具,写isalpha(infx[i])

【讨论】:

我很抱歉没有详细说明infx 的填充方式。它是从使用getline() 的文本文件中读取的行中设置的。我修改了我的源以使用isgraph(infx[i]) 而不是我拥有的,这似乎很容易解决了这个问题。我仍然在处理括号时遇到问题,但我不再在我的后缀行上得到垃圾输出。我确实有一个我想要a-z, A-Z, * / + - ( ) 的字符列表,但很明显,对于这个分配,我只需要担心空格和回车。感谢您的帮助!

以上是关于使用链表堆栈的中缀到后缀转换器的主要内容,如果未能解决你的问题,请参考以下文章

数组模拟实现一个50个字符串的堆栈,使用堆栈,将中缀算术表达式转换成后缀表达式。

数组模拟实现一个50个字符串的堆栈,使用堆栈,将中缀算术表达式转换成后缀表达式。

数组模拟实现一个50个字符串的堆栈,使用堆栈,将中缀算术表达式转换成后缀表达式。

中缀表达式转换成后缀表达式并求值

线性结构(链表栈和队列中缀前缀后缀表达式转换)

在 Scala 中将中缀转换为后缀表示法