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) のような単純な文字列を使用してテストすると、「+」記号も正しく配置されません。Queue は 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

したがって、操作をスタックに配置していますただし、後でそれをスタックから取り出し、次の桁をキューに入れる前にキューに入れます。

これは間違いなく間違った順序ですが、コードを調べると、2 行の順序が間違っている単なる小さなスニペットではありません (簡単すぎます)。

スタックからキューへの転送を行っているコードは、1 文字ごとにwhileすべてのアイテムをスタックからキューに転送する最終ループでmain()あり、事実上スタックを不要にします。

それはあなたが見ているべき場所ですが、私はあなたに手がかりを与えます. 数値を含むものについてのみ、すべての文字の後にスタックをキューに転送したくありません。

その問題を解決した後に他の問題が発生する可能性がありますが、その方法 (重要なことを行うたびに出力をデバッグする) は、発生した問題を修正するのに十分な情報を提供できるはずです。

于 2015-03-03T02:46:01.343 に答える