[資料結構]--PTA求字首表示式的值
阿新 • • 發佈:2019-01-27
算術表示式有字首表示法、中綴表示法和字尾表示法等形式。字首表示式指二元運算子位於兩個運算數之前,例如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;
}