1.题目
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4
的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4
。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+
、-
、*
、/
以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR
。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
2.题目分析
1.计算方法:首先从右向左开始入栈,当遇到第一个操作符的时候出栈两次计算结果,再将结果入栈,最后输出总结果
坑:数字可能是小数或者负数!!!!!!!!!!!!
2.记住:输入时为反着的,要输出为正,类似这样的情况可以使用栈
3.atof使用#include<cstdlib>头节点
4.getline(cin, list);//注意C++中一次输入一行的写法,该写法需要#include<string>头文件,但是会有换行符
3.代码
#include<iostream>
#include<stack>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>//atof使用
using namespace std;
int main()
{
stack<double>st;
string list;
getline(cin, list);//注意C++中一次输入一行的写法,该写法需要#include<string>头文件
double answer=0;
for (int i = list.length()-1; i >= 0; i--)//减一是因为getline会获取回车符
{
char aaa = list[i];
answer = 0;
stack<char>templist;//存放整个字符串
bool isnotoperator = false;
while ((list[i] != ' ')&&(isdigit(list[i])||list[i]=='.'))
{
isnotoperator = true;
templist.push(list[i]);//将数字放入临时栈
if (isdigit(list[i - 1]) || list[i - 1] == '.')//如果前面还有数字、小数点接着入栈
i--;
else
break;
}
//char number[31];
//开始使用的是char数组,后来发现一个知名的错误就是数组使用完一次初始化的问题,若不做处理可能这次的数还有上次的残留,(70、4.5 5会残留)较麻烦
string number;
while (!templist.empty())
{
//number[d++]=templist.top();
number=number+ templist.top();
templist.pop();//将数字转为string
}
if (isnotoperator)//如果上面经过了数字的转化计算,这里就将string转为double
{
double b = atof(number.c_str());
if (list[i - 1] == '-'&&i>1)//如果前面为-,就改成负数
{
st.push(-b);//为负数
i--;
}
else
st.push(b);
}
if (list[i] != ' '&&!isdigit(list[i])&&isnotoperator==false)
{
double c, d;
if (st.size() > 1)
{
c = st.top(); st.pop();
d = st.top(); st.pop();
}
else//处理整个表达式只有一个数字的情况
{
if (list[i] == '+')//例如+9.2342342
{
c = st.top(); st.pop();
d = 0;
}
else if (list[i] == '-')//例如-9.2342342
{
c = -1*st.top(); st.pop();
d = 0;
}
}
if (list[i] == '+')answer = answer + c + d;
if (list[i] == '-')answer = answer + (c - d);
if (list[i] == '*')answer = answer + (c*d);
if (list[i] == '/')
{
if (d == 0) { cout << "ERROR" << endl; return 0; }//除数为0直接输出
else answer = answer + (c / d);
}
st.push(answer);
}
}
if(st.size()!=1)cout<< "ERROR" << endl;//防止整个式子不标准,不过好像没用
else printf("%.1f", st.top());
}
//+ + 2 * -20 - 7 4 / 8 4
//+ + -2.5 * 3.4 - 70 -4.5 / 8.3 4.2
//+123.434234
4.清爽明了版
(上面自己写的很恶心,参考https://blog.csdn.net/qq_41608020/article/details/80922359?utm_source=blogxgwz1)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
stack <double> st;
int main()
{
string s;
getline(cin, s);
for (int i = s.size() - 1; i >= 0; i--)
{
if (isdigit(s[i]))
{
double mul = 10, num = s[i] - '0';
for (i--; i >= 0; i--)
{
if (isdigit(s[i]))
{
num += (s[i] - '0') * mul;
mul *= 10;
}
else if (s[i] == '.')
{
num /= mul;
mul = 1;
}
else if (s[i] == '-')
num = -num;
else
break;
}
st.push(num);
}
else if (s[i] != ' ') //else
{
double a, b, sum;
a = st.top();
st.pop();
b = st.top();
st.pop();
switch (s[i])
{
case '+':
sum = a + b;
break;
case '-':
sum = a - b;
break;
case '*':
sum = a * b;
break;
case '/':
{
if (b == 0)
{
cout << "ERROR";
return 0;
}
sum = a / b;
}
}
st.push(sum);
}
}
printf("%.1lf", st.top());
}