1

ほんの数日前に同じプログラムで助けを得た後、助けを求めて戻ってくるのは嫌いですが、私はこのプログラムを完了するのに本当に苦労しています. つまり、5 5 5 + + (=15) などの式を実行できる、連結リスト スタックを備えた後置記法計算機 (RPN) を作成する必要があります。メインの計算部分はなんとかできましたが、2 つのエラーの処理に苦労しています。1 つは「演算子が多すぎる」、もう 1 つは「オペランドが多すぎる」です。現在、「オペレーターが多すぎます」に取り組んでおり、近づいているように感じますが、そこに到達することはできません。

ユーザーが最初のエントリで 5 5 + + を入力すると、それがキャッチされ、「オペランドが多すぎます」と表示されます。ただし、前の計算のスタックに何かが既にある場合、同じ式 5 5 + + を入力すると、スタックが空であるとは言えず、前の数値が使用された答えが出力されます。ここで私が間違っている場所を誰かが見て、他のエラー「オペレーターが多すぎます」(例: 5 5 5 +) を理解する方向に私を指摘してくれれば、それは大歓迎です。よろしくお願いします。

(さらにいじった後、計算を行うほど、空と見なされるために実際に配置する必要がある演算子が増えるようです。各式の前に popVal をどこかに配置する必要があると推測していますが、どこに配置するかはわかりません。私は多くの場所を試しましたが、うまくいきませんでした)

#include<iomanip>
#include<iostream>
#include<string>
#include<sstream>

using namespace std;

class SLLNode
{
    double data;
    SLLNode *top;
    SLLNode *ptr;
public:
    SLLNode()
    {
        top = NULL;
        ptr =  NULL;
    }

    bool isEmpty()
    {
        return top == 0;
    }

    void pushVal(double val)
    {
        SLLNode *next = new SLLNode;
        next -> data = val;
        next -> ptr = top;
        top = next;
    }

    double popVal()
    {
        if (isEmpty())
        {
            cout << "Error: Too many operators" << endl;
        }
        else
        {
        SLLNode *next = top -> ptr;
        double ret = top -> data;
        delete top;
        top = next;
        return ret;
        }

    }

    void print()
    {
        cout << top -> data << endl;
    }
};


bool isOperator(const string& input)
{
    string ops[] = {"+", "-", "*", "/"};
    for(int i = 0; i < 4; i++)
    {
        if(input == ops[i])
        {
            return true;
        }
    }
    return false;
}


void performOp(const string& input, SLLNode& stack)
{
    double fVal, sVal;
    int errorCheck = 0;

    sVal = stack.popVal();
    fVal = stack.popVal();

    if(input == "+")
    {
        stack.pushVal(fVal + sVal);
    }
    else if(input == "-")
    {
        stack.pushVal(fVal - sVal);
    }
    else if(input == "*")
    {
        stack.pushVal(fVal * sVal);
    }
    else if(input == "/" && sVal != 0)
    {
        stack.pushVal(fVal / sVal);
    }


    if(input == "/" && sVal == 0)
    {
        cout << "Error: Division by zero" << endl;
        errorCheck = 1;
    }

    if(errorCheck == 0)
    {
    stack.print();
    }
}

int main()
{
    cout << "::::::::::::::::RPN CALCULATOR:::::::::::::::::" << endl;
    cout << "::TYPE IN A POSTFIX EXPRESSION OR 'q' TO QUIT::" << endl;
    cout << ":::::::::::::::::::::::::::::::::::::::::::::::" << endl << endl;

    string input;
    SLLNode stack;
    while(true)
    {
        cin >> input;
        double num;

        if(istringstream(input) >> num)
        {
            stack.pushVal(num);
        }
        else if (isOperator(input))
        {
            performOp(input, stack);
        }
        else if (input == "q")
        {
            return 0;
        }
    }
}
4

1 に答える 1

0

基本的な考え方は次のとおりです。

  1. 1 行読み取り ( std::getline );
  2. この行を処理します ( std::stringstream );
  3. 答えまたはエラーを出力します。
  4. スタックをクリーンアップします (またはスタックを破棄して、ステップ 2 で新しいスタックを作成します)。
  5. 1 に移動して繰り返します。

あなたが見逃しているのは最初のステップです。stdin からすべてを直接取得する場合は、改行を単純な空白として扱います。

于 2013-11-12T16:51:11.437 に答える