#include <iostream>
#include <stack>
#include <cassert>
using namespace std;
// 获得操作符所对应的比较值
// Expression 公式
//
int EnumOP(char op)
{
switch (op)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '('://把()中的公式看成是新的公式
case '#':
default:
return 0;
}
}
// 用于计算操作数栈中两个数,操作符栈中一个操作符所得的值,并保存在操作数栈中
//eter 操作符栈
//eter 操作数栈
double Operation(stack<char> &Op, stack<double> &Data)
{
//从数据栈中取出两个操作数
assert(Data.size() > 1);//断言,如果表达式中出现语法错误即无法进行
/*
if (Data.size() < 2)
return 0;
*/
double rval = Data.top();
Data.pop();
double lval = Data.top();
Data.pop();
char op = Op.top();
Op.pop();
switch(op)
{
case '+':
return lval + rval;
case '-':
return lval - rval;
case '*':
return lval * rval;
case '/':
{
if (rval != 0)
return lval / rval;
else
{
cout << "division by zero!" << endl;
return 0;
}
}
default:
/*throw new Exception("Operation dosn't take param with ' '");*/
exit(1);
}
}
//计算
//eter 带常量名的表达式
// Expression的值
double Compute(string Expression)
{
assert(!Expression.empty());
stack<double> Data;
stack<char> Op;
int i = 0;
char ch = Expression[i];
Op.push('#');
while (i < Expression.size())
{
if (ch == ' ')//当为空格时读取下一个char
ch = Expression[++i];
if (ch == '(')//当为(时进入操作符栈
{
Op.push(ch);
}
else if (ch == ')')//当为)时把括号里面的操作数计算出来
{
while (Op.top() != '(')
{
//出栈一次操作符,两次数据,进行计算
double result = Operation(Op, Data);
Data.push(result);//把结果放进数据栈中
}
Op.pop();
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
if (EnumOP(ch) <= EnumOP(Op.top()))//当获取的操作符(ch)比栈中top的操作符比较值较小或相等时,进行运算.
{
//出栈一次操作符,两次数据,进行计算
double result = Operation(Op, Data);
//Op.pop();
Data.push(result);//把结果放进数据栈中
}
Op.push(ch);//把新的操作符插入到操作符栈中
}
else if ((ch >= '0' && ch <= '9') || ch == '.')
{
//把本来数值的数据转成double类型
double x = 0;
double y = 0;
do
{
x = x * 10 + ch - '0';
if (++i < Expression.size())//遇到公式最后是数字时判断以离数组越界
ch = Expression[i];
else
break;
}while (ch >= '0' && ch <= '9');
if (ch == '.')
{
ch = Expression[++i];
double j = 10.0;
do
{
y = y + (ch - '0') / j;
j *= 10;
if (++i < Expression.size())
ch = Expression[++i];
else
break;
} while (ch >= '0' && ch <= '9');
}
x += y;
Data.push(x);
continue;
}
if (Op.size() > 1)//由于一开始就把'#'插入到操作符栈中,所以当只有#时为空栈.
ch = Expression[++i];
else
return Data.top();
}
while (Op.size() > 1)//把剩余值计算
{
//出栈一次操作符,两次数据,进行计算
double result = Operation(Op, Data);
//Op.pop();
Data.push(result);
}
return Data.top();
}
//测试
int main()
{
string str;
char expression[128];
//str = "25*2/5+10*2";
//str = " ( 25*2/ 5+10 *2 ) ";
cin.getline(expression, 128);
while (strcmp(expression, "") != 0)
{
str = expression;
cout << Compute(str) << endl;
cin.getline(expression, 128);
}
system("pause");
return 0;
}