算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
————————————
其实如果只是对于一位数就非常简单直接从后向前扫描即可,但是如果要满足两位数可以进栈,就有一点麻烦,需要判断有几位,再将其入栈,我这里用的是链栈,其实可以用顺序栈,就当做一个小小练习吧~
从后向前扫描,如果不是空格就要进行判断,判断有几位,如果是两位就存入临时的数组中,再利用反转(要吐槽这里不能使用库函数的strrev(),只好再重新写一个了。。。)和atof()函数将char[]转换为double类型,如果是一位直接入栈,如果是运算符就让两个数出栈,出栈前要判断是否为空(这里很容易出现错误的情况,如果空直接错误就退出就好~),之后直接进行运算,记得将运算结果入栈。
最后输出判断top的next是不是空就好,就是保证最后链栈只有一个元素,说明正确,其他情况不正确。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 30
//定义链栈
typedef struct snode
{
double data;
struct snode *next;
}StackNode,*LinkStack;
//置空栈
LinkStack top=NULL;
//入栈
LinkStack Push_LinkStack(double x)
{
StackNode *p;
p=(StackNode *)malloc(sizeof(StackNode));
p->data=x;
p->next=top;
top=p;
return top;
}
//出栈
double Pop_LinkStack()
{
double x;
StackNode *p;
if(top==NULL) return 0;
else{
x=top->data;
p=top;
top=top->next;
free(p);
return x;
}
}
//计算
double calcul(double a,double b,char c)
{
switch(c)
{
case '+':
return a+b;
case '-':
return b-a;
case '*':
return a*b;
case '/':
return b/a;
default :
return 0;
}
}
//判栈空
int Empty_SeqStack()
{
if(top==NULL)
return 1;
else
return 0;
}
//字符串反转
char *revstr(char *str, int len)
{
char *start = str;
char *end = str + len - 1;
char ch;
if (str != NULL)
{
while (start < end)
{
ch = *start;
*start++ = *end;
*end-- = ch;
}
}
return str;
}
int main()
{
char s[N];
gets(s);
char temp[N];
char *strrevtemp;
int i;
int j=-1;
double a,b,result;
for(i=strlen(s)-1;i>=0;i--)
{
if(s[i]!=' ')
{
if(s[i-1]==' '||i==0)//判断下一位是不是空格
{
if(s[i]>='0'&&s[i]<='9')
{
Push_LinkStack(s[i]-'0');
i--;
}
else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){
if(!Empty_SeqStack())
a=Pop_LinkStack();
else{
printf("ERROR");
return 0;
}
if(!Empty_SeqStack())
b=Pop_LinkStack();
else{
printf("ERROR");
return 0;
}
if(s[i]=='/'&&b==0)
{
printf("ERROR");
return 0;
}
result=calcul(b,a,s[i]);
Push_LinkStack(result);
}
else{
printf("ERROR");
return 0;
}
}
else{
j=0;
while(s[i]!=' '&&i>=0)
temp[j++]=s[i--];
temp[j]='\0';
if(strlen(temp)<=1)
{
printf("ERROR");
return 0;
}
strrevtemp=revstr(temp,strlen(temp));
Push_LinkStack(atof(strrevtemp));
i++;
}
}
}
if(top!=NULL)
printf("%.1lf",top->data);
else
printf("ERROR");
return 0;
}
本文介绍了一种通过链栈实现的前缀表达式计算方法,包括处理单双位数及运算符的过程,并提供了完整的C语言代码示例。
4932

被折叠的 条评论
为什么被折叠?



