题目是简单表达式求值(支持负数 小数)
表达式中可能的运算符有+,-,*,/,()。
【输入】简单表达式
【输出】表达式的值
//输出的数据类型符合C/C++对表达式求值的定义,即表达式的输出类型由高精度的运算数来决定。
浮点型保留小数点后的3位小数
例如:
【输入】2*(4+5)-12
【输出】6
【输入】2*2.5
【输出】5.000
最后一个用例通不过
但我也不知道哪有问题 我试了的例子都对的
更正:那20个用例我自己试了都通得过 不是代码的问题(无语!!!!!!!!!!)
#include <iostream>
#include<stack>
using namespace std;
const int maxstack = 1000;
void trans(char arr[maxstack], char str[maxstack], bool& flag)//把中序波兰式转后序
{ // 1.数字 2.( 3.) 4.+-*/ 5.负号(表达式开头/括号后开头) 6..小数点(数字之后)
stack<char> s1;//放字符
stack<char> s2;//放数字 (最后全放s2中)
int i = 0;
//bool flag = false;//true--有小数 false--无小数
if (arr[0] == '-')//表达式开头的负号
{
s2.push('0');
s2.push('#');
s1.push('-');
i++;
}
while (arr[i] != '\0')
{
if (arr[i] >= '0' && arr[i] <= '9')//数字(数字串以#结尾)
{
s2.push(arr[i]);
if ((!(arr[i + 1] >= '0' && arr[i + 1] <= '9')) && (arr[i + 1] != '.'))
//到数字结尾了
{
s2.push('#');
}
}
else if (arr[i] == '.')//.
{
s2.push(arr[i]);
flag = true;//标记是小数
}
else if (arr[i] == '(')//(
{
s1.push(arr[i]);
//(后面是-
if (arr[i+1] == '-')
{
s2.push('0');
s2.push('#');
s1.push('-');
i++;
}
}
else if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/')
//+ - * /
{
if (s1.empty())//空 -- 入栈s1
{
s1.push(arr[i]);
}
else
{
char item = s1.top();//s1栈顶运算符
if (item == '(')
{
s1.push(arr[i]);//栈顶是( -- 入栈s1
}
else {//优先级+ = - < * = /
空/栈顶是( -- 将arr[i]入栈s1
//arr[i]优先级比item高-->将arr[i]入栈s1
//否则-->将s1栈顶弹出 入栈s2 -->arr[i]再与新的s1栈顶比较
switch (arr[i]) {
case'+':
case'-':
while (!s1.empty() && item != '(')
{
s1.pop();
s2.push(item);
if (!s1.empty())
{
item = s1.top();
}
else
{
break;
}
}
s1.push(arr[i]);
break;
case'*':
case'/':
if (item == '+' || item == '-')
{
s1.push(arr[i]);
}
else
{
while (!s1.empty() && item != '(' && item != '+' && item != '-')
{
s1.pop();
s2.push(item);
if (!s1.empty())
{
item = s1.top();
}
else
{
break;
}
}
s1.push(arr[i]);
}
break;
}
}
}
}
else if (arr[i] == ')')// )
//依次弹出s1栈顶 压入s2 直到遇到)
{
char item = s1.top();
while (item != '(')
{
s2.push(item);
s1.pop();
item = s1.top();
}
//此时s1栈顶为( --> 将()舍弃
s1.pop();
}
i++;
}
while (!s1.empty())
{
char item = s1.top();
s2.push(item);
s1.pop();
}//现在结果都在s2中
//最后变成后序波兰式 放到str[maxstack]里
int m = 0;
stack<char> s3;
while (!s2.empty())
{
char item = s2.top();
s3.push(item);
s2.pop();
}
while (!s3.empty())
{
str[m] = s3.top();
s3.pop();
m++;
}
str[m] = '\0';
}
void count_value(char str[maxstack], bool flag)//后序波兰式的数组
{
stack<double> s;//放数字
int i = 0;
bool outcome = true;
double x = 0;
double y = 0;
while (str[i] != '\0')
{
if (str[i] >= '0' && str[i] <= '9')//数字--结尾是#
{
int number1[maxstack] = { 0 };
int j = 0;
int number2[maxstack] = { 0 };
int k = 0;
while (str[i] != '#')
{
if (str[i] >= '0' && str[i] <= '9')
{
number1[j] = str[i] - '0';
i++;
j++;
}
else if (str[i] == '.')//小数点
{
i++;
while (str[i] >= '0' && str[i] <= '9')
{
number2[k] = str[i] - '0';
i++;
k++;
}
}
}
double ret1 = 0;
double pow1 = 1;
for (int m = j - 1; m >= 0; m--)
{
ret1 += pow1 * number1[m];
pow1 *= 10;
}
//ret1=小数点前的数值
double ret2 = 0;
double pow2 = 0.1;
for (int m = 0; m < k; m++)
{
ret2 += pow2 * number2[m];
pow2 *= 0.1;
}
//ret2=小数点后的数值
s.push(ret1 + ret2);//把这个小数入栈
}
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
{
if (!s.empty())
{
x = s.top();
s.pop();
if (!s.empty())
{
y = s.top();
s.pop();
}
else {
outcome = false;
}
}
else {
outcome = false;
}
switch (str[i])
{
case '+':
s.push(y + x);
break;
case '-':
s.push(y - x);
break;
case '*':
s.push(y * x);
break;
case '/':
s.push(y / x);
break;
default:
outcome = false;
break;
}
}
i++;
}
if (outcome)
{
if (!s.empty())
{
double key;
key = s.top();
s.pop();
if (s.empty())
{
if (flag)//输出小数
printf("%.3f", key);
else
{
int intkey = key;
printf("%d", intkey);
}
}
else { cout << "输入不合法"; }
}
else { cout << "输入不合法"; }
}
else
{
cout << "输入不合法";
}
}
int main()
{
char arr[maxstack];
int i = 0;
arr[i] = cin.get();
while (arr[i] != '\n')
{
i++;
arr[i] = cin.get();
}
arr[i] = '\0';//把输入的都放数组中
char str[maxstack];
bool flag = false;//true--有小数 false--无小数
trans(arr, str, flag);//把中序波兰式转后序
count_value(str, flag);//后序波兰式求值
return 0;
}