[解決済み】C++用RPN電卓
2022-02-18 19:12:03
質問
RPN電卓のコードを書こうとしているのですが、複数のオペランドを正しく計算させることに苦労しています" left" と " right" です。
今のところ、私のコードは次のような入力に対して動作しています。 10 15 + = 25
これらの入力を正しく出力させる方法がわからなくて困っています。
入力 100 10 50 25 / * - -2 / = 出力。-40
また、今はスタックサイズを2で割っていますが、これはエラーチェックの一部には有効ですが、上記/下記のような入力ではエラーが表示されます。 100 10 50 25 / * - -2 / = -40
以下の2つの入力に対してエラーチェックを行うようにするにはどうしたらよいでしょうか?
入力 10 20 * / = 出力。 Error: 演算子が多すぎる
12 20 30 / = Error: Too many operand
何かお手伝いいただけると助かります、ありがとうございます
#include <iostream>
#include <stack>
#include <string>
#include <sstream> //make use of a class called istringstream
#include<iomanip>
using namespace std;
//Function prototype for isOperator
bool isOperator(const string& input);
//Function prototype for perforOperation
int performOperation(const string& input, stack<double>& calcStack);
int main()
{
cout << "RPN Calculator: " << endl;
cout << "Input\n";
stack<double> calcStack;
string input;
while(input != "0")
{
//Terminate program when 0 is entered by user
while(input != "=")
{
// get input
cin >> input;
// check for being numeric value
double num;
if(istringstream(input) >> num)
{
//use push function
calcStack.push(num);
}
// check for operator
else if(isOperator(input))
{
performOperation(input, calcStack);
}
// If user enters 0 on a line followed by a new line, the program exits ????????????
else if(input == "0\n")
{
return -1;
}
// invalid output check
//else
//{
//cout << "Invalid input" << endl;
//}
}
}
}
bool isOperator(const string& input)
{
string operators[] = {"-", "+", "*", "/"};
for(int i=0; i<4; i++)
{
if(input == operators[i])
{
return true;
}
}
return false;
}
int performOperation(const string& input, stack<double>& calcStack)
{
double firstOperand;
double secondOperand;
double result;
if( calcStack.size() > 2 ) //Error check gives a false error for last input ???
{
cout << "Error: too many operands" << endl;
return 1;
}
//Error chceck for too many operators ////STILL PRINT OUTPUT???
if( calcStack.size() < 2 )
{
cout << "Error: too many operators" << endl;
return 1;
}
secondOperand = calcStack.top();
calcStack.pop();
firstOperand = calcStack.top();
calcStack.pop();
if(input == "-")
{
result = firstOperand-secondOperand;
}
else if (input == "+")
{
result = firstOperand + secondOperand;
}
else if (input == "*")
{
result = firstOperand * secondOperand;
}
else if( input == "/")
{
result = firstOperand / secondOperand;
}
// If user enters 0 on a line followed by a new line, the program exits ???????????
else if(input == "0\n")
{
return -1;
}
//Division by zero error
if(secondOperand == 0)
{
cout << "Error: Division by 0.\n";
return -1;
}
cout << "Output\n";
cout << result << endl;
calcStack.push(result);
return 0;
}
解決方法は?
このコードのビットはこちら
if( calcStack.size() > 2 )
{
cout << "Error: too many operands" << endl;
return 1;
}
メインに移動して若干の変形が必要
else if(isOperator(input))
{
performOperation(input, calcStack);
}
else if(input == "=")
{
if (calcStack.size() != 1)
{
cout << "Error: too many operands" << endl;
return 1;
}
else
{
cout << "Result: " << calcStack.top();
// now decide whether or not you are preserving the result for
// the next computation
calcStack.pop(); // Assuming not keeping result
}
}
そして、このループを見直す必要があるということです。
while(input != "=")
本当に惜しいことをしましたね。
2つの提案
isOperator関数を最適化することができます。
bool isOperator(const string& input)
{
static const string operators ="-+*/";
if (input.length() == 1) // right size to be an operator.
{
return operators.find_first_of(input[0]) != string::npos;
// look in the operator string for the first (and only) character in input
}
return false;
}
また、演算子には1文字しかないことが分かっているので、if/else if よりもエレガントなものを使うことができます。
switch (input[0])
{
case '-':
result = firstOperand - secondOperand;
break;
case '+':
result = firstOperand + secondOperand;
break;
case '*':
result = firstOperand * secondOperand;
break;
case '/':
if (secondOperand == 0)
{ // moved this test to here because it's the only place it matters.
cout << "Error: Division by 0.\n";
return -1;
}
result = firstOperand / secondOperand;
break;
}
コメントへの対処のための追記
この時点であなたのコードはかなり変わっているはずなので、現在のコードで新しい質問を始めたくなるかもしれません。そうでない場合は、これがコメント欄で話していることです。
else if(isOperator(input))
{
if (performOperation(input, calcStack) != 0)
{
// empty out the stack and delete all pending user input.
calcStack.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Bad input. Try again." << endl;
break; // exit input loop.
}
}
else if(input == "=")
{
...
関連
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】'cout'は型名ではない
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】C++の余分な資格エラー
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み】高放射能環境下で使用するアプリケーションのコンパイルについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】変数やフィールドがvoid宣言されている