输入一个正确的字符串,包含的元素可以有数字,小数点,运算符号和括号,计算并输出该表达式的计算结果。
例如:
- 输入表达式3.4 输出3.40
- 输入表达式:7+8.3 输出:15.30
输入样列:
3+4.5*(7+2)*(3)*((3+4)*(2+3.5)/(4+5))-34*(7-(2+3))
输出样列:
454.75
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cstring>
using namespace std;
/*
这破代码居然没考虑负数的情况,有兴趣的小伙伴可以自己试试哟
*/
char a[100];
int i = 0, n; //:i表示运算到了什么位置
double cul(double k, double m, char c) //:计算 k c m 的值
{
switch (c)
{
case '+': return k + m; break;
case '-': return k - m; break;
case '*': return k * m; break;
case '/': return k / m;
}
}
double getnum(vector<double> sum, vector<char> sign) //:只含加减法的表达式求值,不能从后往前算
{
int m = sign.size();
double num = sum[0];
for (int j = 0; j < m; j++)
{
num = cul(num, sum[j + 1], sign[j]);
}
return num;
}
double info()
{
vector<double> sum;
vector<char> sign;
while (i < n && a[i] != ')')
{
if (a[i] >= '0' && a[i] <= '9') //:遇见的是数字
{
double num = atof(a + i); //:atof函数将字符串转化为double型小数
if (!sign.empty()) //:判断该数字前面是否是乘法或者是除法,若是,则先进行运算,实现优先级
{
char yunsuan = sign.back();
if (yunsuan == '*' || yunsuan == '/') //:运算之后一定要记得将之前的数删掉
{
double m = sum.back();
sum.pop_back();
double k = cul(m, num, yunsuan);
sign.pop_back();
sum.push_back(k);
}
else sum.push_back(num);
}
else sum.push_back(num);
while (a[i] <= '9' && a[i] >= '0' || a[i] == '.') i++; //:不要忘记小数点啊
}
else if (a[i] != '(') //:不是数也不是左括号,那只能是运算符号了
{
sign.push_back(a[i]);
i++;
}
else //:遇见左括号了,进行递归,即可求出括号中的值
{
i++;
double p = info();
if (!sign.empty())
{
char yunsuan = sign.back();
if (yunsuan == '*' || yunsuan == '/')
{
double m = sum.back();
sum.pop_back();
double k = cul(m, p, yunsuan);
sign.pop_back();
sum.push_back(k);
}
else sum.push_back(p);
}
else sum.push_back(p);
}
}
if (a[i] == ')') i++;
return getnum(sum, sign);
}
int main()
{
cin >> a;
n = strlen(a);
double p = info();
cout << p << endl;
return 0;
}