0

だから、私は次の(kludgy!)中置から後置式へのコンバーターと計算機のコードを持っています(前の投稿で述べたように:単純な数値式ソルバー、みんなに感謝します!):

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

using namespace std;

int main()
{
    stack<char> operators;  
    stack<char> output;
    stack<char> temp;       
    stack<char> answer; 

    string command;

    cout << "=>";
    cin >> command;

    // "Shunting Yard" algorithm
    // source: http://en.wikipedia.org/wiki/Shunting-yard_algorithm
    for(int i=0; i<command.size(); i++)
    {
        switch(command[i])
        {
        case '*': case '+': case '-': case '/': case'(': 
            operators.push(command[i]);
            break;

        case ')':
            while(operators.top() != '(')
            {
                output.push(operators.top());
                operators.pop();
            }
            operators.pop();
            break;

        default:
            output.push(command[i]);
            break;
        }
    }

    while(!operators.empty())
    {
        output.push(operators.top());
        operators.pop();
    }

    while(!output.empty())
    {
        temp.push(output.top());
        output.pop();
    }

    while(!temp.empty())
    {
        if(temp.top() == '+')
        {
            int a = atoi(&answer.top());
            cout << "A=" << a << endl;
            answer.pop();
            int b = atoi(&answer.top());
            cout << "B=" << b << endl;
            answer.pop();
            answer.push(b+a);
        } else {
            answer.push(temp.top());
        }
        temp.pop();
    }

    cout << answer.top() << endl;

    system("pause");
    return 0;
}    

とにかく、問題は次のとおりです。たとえば、3 + 4と入力すると、結果は「&」になりますが、正しい結果は「7」になります。だから、私のコードの何が問題になっていますか?

4

2 に答える 2

0

コードのこのセクションを置き換える:

if(temp.top() == '+')
    {
        int a = atoi(&answer.top());
        cout << "A=" << a << endl;
        answer.pop();
        int b = atoi(&answer.top());
        cout << "B=" << b << endl;
        answer.pop();
        answer.push(b+a);
    } 

と:

 if(temp.top() == '+')
    {
        int a = answer.top() - '0';
        cout << "A=" << a << endl;
        answer.pop();
        int b = answer.top() - '0';
        cout << "B=" << b << endl;
        answer.pop();
        answer.push(b+a);
    } 

あなたの問題を解決します。

于 2012-06-26T03:36:02.577 に答える
0

ここには 2 つの問題があります。

初め:

int a = atoi(&answer.top());

atoi は、NULL で終わる文字列へのポインタを取ります。しかし、&answer.top() は 1 つの文字へのポインターにすぎません。そのため、atoi はその文字から読み取りを開始し、'\0' 文字 (または非数字) が見つかるまでメモリ内を移動し続けます。プラットフォームでのスタックの実装方法によっては、「4」、「3」、「\0」の順に読み取られるため、最終的に「43」になることがあります。または、「4」を読み取り、「8675309j」で始まる初期化されていないメモリを読み取る可能性があるため、「48675309」で終了します。

なぜコンパイラがこのエラーについて警告しないのか疑問に思っている場合、問題は、C スタイルの文字列と単一文字へのポインタが構文的にまったく同じ型 (char*) であるため、コンパイラが通知できないことです。 atoi のセマンティクスを理解しない限り、それらを混同しています。これは、C の char* ベースの関数ではなく、C++ の文字列クラスと関数を使用する方がよい理由の 1 つです。

2番:

answer.push(b+a);

b+a は int ですが、文字のスタックにプッシュしています。したがって、正しい値があったとしても、文字「7」ではなく文字「\007」をプッシュすることになります。再ストリング化する必要があります。しかし、この場合、たとえば 305419814 のようなものが得られたようです。これは、char にキャストすると下位 8 ビット (38) に切り捨てられ、38 は「&」です。

于 2012-06-26T04:38:19.113 に答える