後置記法方程式を評価する関数を C++ で記述しようとしています。私の一般的な戦略は、文字列をスキャンすることです(適切な形式、たとえば「10 20 + 30 -」)。
インデックス変数 i をインクリメントすることでこれを行っています。インクリメントごとに、その文字が数字か演算子か、またはそのどちらでもないかを確認します。数字の場合は、getNextNum() 関数を使用して後続のすべての数字を取得し、それを float に変換してから、スタックにプッシュします。また、キャプチャした数値の長さだけ i をインクリメントします。文字が演算子の場合、スタックの上位 2 つの要素を取得し、演算を実行してから、結果をスタックにプッシュします。
問題は、while ループが 1 回しか通過しないように見えることです。この関数は、文字列の最初の数値のみを返します。何が問題なのかわかりません。助けていただければ幸いです。while ループに cout ステートメントを挿入しましたが、i は最初の数値の後のインデックスまでインクリメントするだけです。
編集: OK、getNextNum() 関数を追加しました。また、evalPostfix() を strLength の cout で更新し、while ループの各反復後に i も更新しました。指定されたコードを実行すると、次のようになります。
Running…
Please enter an expression in postfix notation: 555 666+
3
555
3
Your expression evaluates to: 555
strLength が本来よりも小さく設定されているようです。これはなぜですか?
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
string getNextNum(string equation, int i);
float evalPostfix(string postfix);
float doOperation(float x, float y, char op);
float doOperation(float x, float y, char op)
{
switch (op) {
case '+':
return x + y;
case '-':
return x - y;
case '*':
return x * y;
case '/':
return x / y;
default:
return 0.0;
}
}
string getNextNum(string equation, int i)
{
string num = "";
const string DELIM = "+-*/%^ ";
while (i<equation.length()) {
// Iterate through equation until you hit a delimiter.
if (DELIM.find(equation[i]) != -1) {
break;
}
num += equation[i];
i++;
}
return num;
}
float evalPostfix(string postfix)
{
const string OPS = "+-*/%^";
const string NUMS = "0123456789";
int strLength = postfix.length();
stack<float> numStack;
int i = 0;
cout << strLength << endl;
while (i<strLength) {
if (NUMS.find(postfix[i]) != -1) {
// If a character is a digit, then you should get the
// value and push it to the stack (could be multiple characters long).
string sNextNum = getNextNum(postfix, i);
float fNextNum = atof(sNextNum.c_str());
numStack.push(fNextNum);
cout << sNextNum << endl;
i += (sNextNum.length() - 1);
}
else if (OPS.find(postfix[i] != -1)) {
// Otherwise, pop the top two elements of the stack, perform the
// operation, then push the result back to the stack.
char op = postfix[i];
float x = numStack.top();
numStack.pop();
float y = numStack.top();
numStack.pop();
float z = doOperation(x, y, op);
numStack.push(z);
}
i++;
cout << i << endl;
};
// Once the entire string has been scanned through, there should be a float
// left in the stack, simply return that.
return numStack.top();
}
int main ()
{
cout << "Please enter an expression in postfix notation: ";
string postfix;
cin >> postfix;
float eval = evalPostfix(postfix);
cout << "Your expression evaluates to: " << eval;
return 0;
}