0
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include "NodeType.h"
using namespace std;

// Test if token is an operator
bool isOperator(char token);

int getPrecedence(char token);

bool comparePrecedence(char tokenA, char tokenB);


int main()
{

    stack<char> tokenStack;
    queue<char> tokenQueue;
    string expression= "", postfix= "";
    char x;
    cout<<"Please enter a mathematical expression: "<<endl;
    getline(cin, expression);
    cout<<expression.length()<<endl;
    for(int i = 0; i <= expression.length(); i++)
    {
        x = expression[i];
        if(isdigit(x))
        {
            tokenQueue.push(x);
        }
        if(isOperator(x))
        {
            while((!tokenStack.empty()) && (comparePrecedence(x, tokenStack.top() == true)))
            {
               char z = tokenStack.top();
               tokenQueue.push(z);
               tokenStack.pop();
            }
            tokenStack.push(x);
        }
        if(x == '(')
        {
            tokenStack.push(x);
        }
        if(x == ')')
        {
            while((!tokenStack.empty()) && (tokenStack.top() != '('))
            {
                char z = tokenStack.top();
                tokenQueue.push(z);
                tokenStack.pop();
            }
            tokenStack.pop();
        }
        while(!tokenStack.empty())
        {
            char z = tokenStack.top();
            tokenQueue.push(z);
            tokenStack.pop();
        }
    }

    return 0;
}

int getPrecedence(char token)
{
    if((token == '+') || (token == '-'))
    {
        return 1;
    }
    else if((token == '*') || (token == '/'))
    {
        return 2;
    }
    else if ((token == '(') || (token == ')'))
        return 0;
    else
        return 99;
}

// Test if token is an operator
bool isOperator(char token)
{
    return token == '+' || token == '-' ||
    token == '*' || token == '/';
}

bool comparePrecedence(char tokenA, char tokenB)
{
    if(getPrecedence(tokenA) < getPrecedence(tokenB))
        return true;
    else
        return false;
}

由于某种原因,我无法让我的代码正常工作。它总是抛出 Thread 1: EXC_BAD_ACCESS (code=EXC_1386_GPFLT) 错误。当我使用简单的字符串进行测试时,它也没有正确放置“+”号:(3+4)。队列应该看起来像:34+,但它持有 3+4。在我看来,“+”运算符永远不会被压入堆栈。谁能帮我找到我应该关注的重点?

4

1 回答 1

1

调试代码是一项有价值的学习技能,我认为它应该成为学校课程中重要的一部分。

例如,如果您修改代码以输出所有堆栈和队列操作:

int main()
{

    stack<char> tokenStack;
    queue<char> tokenQueue;
    string expression= "", postfix= "";
    char x;
    cout<<"Please enter a mathematical expression: "<<endl;
    getline(cin, expression);
    cout<<expression.length()<<endl;
    for(int i = 0; i <= expression.length(); i++)
    {
        x = expression[i];
        if(isdigit(x))
        {
            tokenQueue.push(x);
            cout << "qpush A " << x << '\n';
        }
        if(isOperator(x))
        {
            while((!tokenStack.empty()) && (comparePrecedence(x, tokenStack.top() == true)))
            {
               char z = tokenStack.top();
               tokenQueue.push(z);
               cout << "spop  G " << z << '\n';
               cout << "qpush B " << z << '\n';
               tokenStack.pop();
            }
            tokenStack.push(x);
            cout << "spush E " << x << '\n';
        }
        if(x == '(')
        {
            tokenStack.push(x);
            cout << "spush F " << x << '\n';
        }
        if(x == ')')
        {
            while((!tokenStack.empty()) && (tokenStack.top() != '('))
            {
                char z = tokenStack.top();
                tokenQueue.push(z);
                cout << "spop  H " << z << '\n';
                cout << "qpush C " << z << '\n';
                tokenStack.pop();
            }
            cout << "spop  I " << tokenStack.top() << '\n';
            tokenStack.pop();
        }
        while(!tokenStack.empty())
        {
            char z = tokenStack.top();
            tokenQueue.push(z);
            cout << "spop  J " << z << '\n';
            cout << "qpush D " << z << '\n';
            tokenStack.pop();
        }
    }

    return 0;
}

并使用简单的 运行它3+4,您将看到以下输出:

qpush A 3
spush E +
spop  J +
qpush D +
qpush A 4

因此,您操作放在堆栈上。但是,您稍后将其从堆栈中取出并将其放入队列中,然后再将下一个数字放入队列中。

这绝对是错误的顺序,但是,如果您检查代码,它不仅仅是一个包含两行错误顺序的小片段(这太容易了)。

执行从堆栈到队列的传输的代码是最后一个while循环,在main()该循环中,在每个字符之后,将所有项目从堆栈传输到队列,从而有效地使您的堆栈变得多余。

那是你应该看的地方,但我会给你一个线索。您不想在每个字符之后将堆栈转移到队列,仅适用于那些涉及数字的字符。

在你解决了那个问题之后很可能还有其他问题,但是那个方法(每次你做一些重要的事情时调试输出)应该能够为你提供足够的信息来解决任何问题。

于 2015-03-03T02:46:01.343 回答