3-8 求前缀表达式的值 (20 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、/以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
输入样例:
-
- 2 * 3 - 7 4 / 8 4
结尾无空行
输出样例:
13.0
明明那个就是照着人家的C++代码改的,也运行出来了,但是就是答案不正确
- 2 * 3 - 7 4 / 8 4
#include<stdio.h>
int main()
{
char temp1,str[1000];
double stack [1000];
int k=0,top=-1;
double res=0;
while((temp1=getchar())!='\n')
{
if(temp1==' ')
temp1='#';
str[k++]=temp1;
}
str[k]='\0';
for(int i=k-1;i>=0;--i)//从右向左遍历
{
if(str[i]=='#')continue;//空格继续
if(str[i]>='0'&&str[i]<='9')
{
double num=str[i]-'0',mul=10;
i--;
for(;i>=0;--i)//解决连续数字
{
if(str[i]>='0'&&str[i]<=9)
{
num+=(str[i]-'0')*mul;
mul=mul*10;
}
else if(str[i]=='.')//解决小数点的问题
{
num=num/mul;//说明刚刚求出的是小数,除以mul就是小数了
mul=1;
}
else if(str[i]=='-')//解决负号问题
{
num=-num;
}
else
break;
}
stack[++top]=num;//是数字就进栈
}
else//是运算符的话就从栈里取出两个数进行运算
{
double l=stack[top--];
double r=stack[top--];
if(str[i]=='+')res=l+r;
if(str[i]=='-')res=l-r;
if(str[i]=='*')res=l*r;
if(str[i]=='/')
{
if(r==0)
{
printf("ERROR\n");
return 0;
}
else
res=l*1.0/r;
}
stack[++top]=res;
}
}
printf("%.1f\n",stack[top]);
return 0;
}
这是别人的代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std;
char str[200005];
stack<double>s;
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
char temp;
int k = 0;
while ((temp = getchar()) != '\n')
{
if (temp == ' ')
temp = '#';
str[k++] = temp;
}
str[k] = '\0';
int cnt = 0;
for (int i = k - 1; i >= 0; --i)
{
if (str[i] == '#') continue;
if (str[i] >= '0' && str[i] <= '9')
{
double num = str[i] - '0', mul = 10;
i--;
for (;i >= 0; --i)
{
if (str[i] >= '0' && str[i] <= '9')
{
num += (str[i] - '0') * mul;
mul *= 10;
}
else if (str[i] == '.')
{
num /= mul;
mul = 1;
}
else if (str[i] == '-')
{
num = -num;
}
else
break;
}
s.push(num);
}
else
{
double l = s.top(); s.pop();
double r = s.top(); s.pop();
double res;
if (str[i] == '+') res = l + r;
if (str[i] == '-') res = l - r;
if (str[i] == '*') res = l * r;
if (str[i] == '/')
{
if (r == 0)
{
printf("ERROR\n");
return 0;
}
res = l * 1.0 / r;
}
s.push(res);
}
}
printf("%.1lf\n", s.top());
return 0;
}
我试一下自己写个栈吧
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
double data[30];
int top;
}Stack;
Stack* Init();
Stack* Init()
{
Stack *s;
s=(Stack*)malloc(sizeof(Stack));
s->top=-1;
return s;
}
int Empty_Stack(Stack*s);
int Empty_Stack(Stack*s)
{
if(s->top==-1)
return 1;
return 0;
}
int Push_Stack(Stack*s,double x);
int Push_Stack(Stack*s,double x)
{
if(s->top==29)
return 1;
else
{
s->top++;
s->data[s->top]=x;
return 1;
}
}
double Pop_Stack(Stack *s);
double Pop_Stack(Stack *s)
{
double x;
if(Empty_Stack(s))
return 0;
else
{
x=s->data[s->top];
s->top--;
return x;
}
}
double Top_Stack(Stack*s);
double Top_Stack(Stack*s)
{
double x;
if(Empty_Stack(s))
return 0;
else
{
x=s->data[s->top];
return x;
}
}
int main()
{
char temp1,str[30];
int k=0;
Stack *s;
s=Init();
while((temp1=getchar())!='\n')
{
if(temp1==' ')
temp1='#';
str[k++]=temp1;
}
str[k]='\0';
for(int i=k-1;i>=0;i--)//从右向左遍历
{
if(str[i]=='#')continue;//空格继续
if(str[i]>='0'&&str[i]<='9')
{
double num=str[i]-48,mul=10;
if(str[i-1]!='#')
{
i--;
for(;i>=0;i--)//解决连续数字
{
if(str[i]>='0'&&str[i]<=9)
{
num+=(str[i]-'0')*mul;
mul=mul*10;
}
else if(str[i]=='.')//解决小数点的问题
{
num=num/mul;//说明刚刚求出的是小数,除以mul就是小数了
mul=1;
}
else if(str[i]=='-')//解决负号问题
{
num=-num;
}
}
}
Push_Stack(s,num);//是数字就进栈
}
else//是运算符的话就从栈里取出两个数进行运算
{
double l=Pop_Stack(s);
double r=Pop_Stack(s);
double res=0;
if(str[i]=='+')res=l+r;
if(str[i]=='-')res=l-r;
if(str[i]=='*')res=l*r;
if(str[i]=='/')
{
if(r==0)
{
printf("ERROR\n");
return 0;
}
else
res=l*1.0/r;
}
Push_Stack(s,res);
}
}
printf("%.1f\n",Top_Stack(s));
}
写完了还是不对,原来是
!!!没加引号
拜拜了
还是说一下这题思路吧,就是前缀表达式求值,从右向左遍历,遇到数字就把它入栈,遇到符号就把它从栈里拿出来,需要注意的是符号,多位数,小数,除法错误的问题