思路:
找到最低级的运算符,然后分成左右两边进行计算,最后再根据这个运算符进行运算,把两边的结果加(减,乘,除)。
代码
// calculator.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include<iostream>
#include <iomanip>
using namespace std;
template <class T>
class calc
{
private:
int GetLowestOperator(string a);
int Find(string str,int begins);
double toInt(string str);
public:
T Calculate(string str);
};
template <class T>
int calc<T>::GetLowestOperator(string a) //查找优先级最低的运算符
{
int i,k;
i = a.length() - 1;
k = 0;
while (i >= 0)
{
if (a[i] == '+' || a[i] == '-') return i;
else if (a[i] == '*' || a[i] == '/')
{
k = i;
--i;
}
else if (a[i] == ')') i = calc<T>::Find(a,i);//如果一个运算符在括号中,优先级绝对不是最高的(除非这个表达式是被一对括号括起来的)
else --i;
}
return k;
}
template <class T>
int calc<T>::Find(string str,int begins)
{
int brackets = 1;
int i = begins;
while (brackets > 0 && i >= 1)
{
--i;
if (str[i] == ')') brackets++;
if (str[i] == '(') brackets--;
}
return i;
}
template <class T>
T calc<T>::Calculate(string str)
{
int lowest = this->GetLowestOperator(str);
T returnValue = 0;
if (lowest == 0 && str[0] != '(' && str[str.length()-1] != ')'&& str[0] != '-')//如果已经是一个数字了,那么就返回(如果这个数字是负数再在后面处理)
{
return this->toInt(str);
}
else
{
if (str[0] == '(' && str[str.length()-1] == ')' && lowest == 0) returnValue = Calculate(str.substr(1,str.length()-2));
else if (str[0] == '-') returnValue = Calculate("0"+str);//如果这个表达式以负数开头,那么就化成非负数的运算
else if (str[lowest] == '+')
{
returnValue = Calculate(str.substr(0,lowest)) + Calculate(str.substr(lowest+1,str.length()-lowest));
}
else if (str[lowest] == '-')
{
returnValue = Calculate(str.substr(0,lowest)) - Calculate(str.substr(lowest+1,str.length()-lowest));
}
else if (str[lowest] == '*')
{
returnValue = Calculate(str.substr(0,lowest)) * Calculate(str.substr(lowest+1,str.length()-lowest));
}
else if (str[lowest] == '/')
{
returnValue = Calculate(str.substr(0,lowest)) / Calculate(str.substr(lowest+1,str.length()-lowest));
}
}
return returnValue;
}
template <class T>
double calc<T>::toInt(string str)//化成数字
{
double value;
value = 0;
bool decimal = false;
double addValue = 1;
for (int i = 0;i < str.length();++i)
{
if (str[i] == '.')
{
decimal = true;
}
else if (str[i] == '(' || str[i] == ')' || str[i] == '.') continue;
else if (decimal)
{
addValue /= 10;
value = value + addValue * (str[i] - '0');
}
else
{
value *= 10;
value += str[i] - '0';
}
}
return value;
}
int _tmain(int argc, _TCHAR* argv[])
{
calc<double> calculator;
string str;
cin >> str;
double result;
result = calculator.Calculate(str);
cout.setf(ios::fixed,ios::floatfield);
cout << setprecision(2) << result << endl;
return 0;
}