[英]C++ Infix to Postfix Conversion and Calculator
我是 stackoverflow 的新手,并且有大学数据结构课程的期末项目。 对于我的项目,我正在创建一个计算器,它从输入中获取数学表达式,例如 (11-2)/3*(15+2/1)-6,并做两件事:
1) 将表达式从中缀表示法转换为后缀表示法 2) 使用后缀表示法计算表达式的值
我已经非常接近最终产品,但我的问题是该程序只能采用数字 0-9,因为我目前的代码方式是转换函数将输入评估为字符串,因此数字大于9(即双/三位数)将使评估功能失效。 我怎样才能将这些数字检测为整数(或浮点数/双精度数)并将它们置于评估函数可以处理的格式(与运算符)中?
此外,我需要创建异常类(不正确的括号、被零除、字母/非操作数/非运算符等)。 我什至对什么是异常类都没有了解太多,所以我不确定我是如何写这些的。 我知道它与 throw/catch 函数有关,但欢迎任何输入(或指向我可以找到简单解释的方向)。 我在下面粘贴了我的代码:
#include <iostream>
#include <ctype.h>
#include <stack>
#include <ItemType.h>
using namespace std;
string getPostfix( string str );
double evaluate( string str );
bool hasPrecedence( char a, char b );
int main()
{
cout << "Welcome to the calculator!" << endl;
string infixString;
string postFixString;
bool valid = false;
cout << "Enter the expression you would like to evaluate: ";
getline( cin, infixString ); // get expression as string
postFixString = getPostfix( infixString ); // convert to postfix
cout << postFixString << endl;
cout << "The value of the given expression is: " << evaluate( postFixString ) << endl; // output evaluated expression
return 0;
}
string getPostfix( string str ) // function to convert infix to postfix
{
string postFixStr; // converted string
stack<char> stack; // stack for operators
for ( int i = 0; i < str.length(); i++ )
{
if ( isdigit( str[i] ) ) // if str[i] is a digit (0-9), add to postfix string
postFixStr += str[i];
else if ( str[i] == '(' ) // if str[i] is an opening parenthesis, push to stack
stack.push( str[i] );
else if ( str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ) // if an operator...
{
if ( stack.empty() || stack.top() == '(' ) // ... push to stack if stack is empty or top of stack is opening parenthesis
{
stack.push( str[i] );
}
else if ( hasPrecedence( str[i], stack.top() ) ) // ... if the operator has higher precedence, push to stack
{
stack.push( str[i] );
}
else // ... if neither of the above cases, add operator already in stack to string, pop it, and push the new operator to stack
{
postFixStr += stack.top();
stack.pop();
stack.push( str[i] );
}
}
else if ( str[i] == ')' ) // ... if str[i] is closing parenthesis, add to string and pop until opening parenthesis is reached
{
while ( stack.top() != '(' )
{
postFixStr += stack.top();
stack.pop();
}
if ( stack.top() == '(' )
stack.pop();
}
}
while ( ! stack.empty() ) // after string has been iterated, add the remainder of the stack to the string
{
postFixStr += stack.top();
stack.pop();
}
return postFixStr;
}
double evaluate( string str ) // function to evaluate postfix expression
{
int op1, op2;
stack<int> stack;
for ( int i = 0; i < str.length(); i++ ) // iterate through postfix string
{
if ( isdigit( str[i] ) ) // if a digit, push to stack as int value
stack.push( str[i] - 48 );
else if ( str[i] == '+' ) // cases for different operators
{
op1 = stack.top(); // assign top int to op1
stack.pop(); // pop top
op2 = stack.top(); // assign next into to op2
stack.pop(); // pop top
stack.push( op1 + op2 ); // add op1 and op2, push result to stack
}
else if ( str[i] == '-' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 - op2 );
}
else if ( str[i] == '*' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 * op2 );
}
else if ( str[i] == '-' )
{
op1 = stack.top();
stack.pop();
op2 = stack.top();
stack.pop();
stack.push( op1 / op2 );
}
}
return stack.top(); // return final value
}
bool hasPrecedence( char a, char b ) // function to determine operator precedence
{
int aWeight, bWeight = 2;
if ( a == '*' || a == '/' )
aWeight = 2;
else
aWeight = 1;
return aWeight >= bWeight;
}
感谢大家的回复。 在查看了你们所有发布的解决方案并从中收集了想法之后,我找到了一个非常简单的解决方案来解决我的具体情况。
在我的 getPostFix 函数中,我在每个插入 postFixStr 的字符后添加了空格,然后使用这些空格作为分隔符,我能够将它添加到我的评估函数中的第一个“if”语句中:
if ( isdigit( str[i] ) )
{
double value = 0;
while ( i < str.length() && isdigit( str[i] ) ) // if a digit, push to stack as double value
{
value = ( value * 10 ) + ( str[i] - '0' );
i++;
}
stack.push(value);
}
注意,* 10 是将之前的值移动到 10 位(或 100 位 + 位),而-'0'
是我之前将 ascii 值更改为算术值的-49
的稍微清晰的版本.
我希望这对将来的人有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.