算數表示式求值
阿新 • • 發佈:2018-12-30
連結串列模擬棧
#include<bits/stdc++.h>
#define maxn 30
using namespace std;
unsigned char Prior[8][8] =
{ //運算子優先順序表
// '+' '-' '*' '/' '(' ')' '#' '^'
{'>','>','<','<','<','>','>','<'},
{'>','>','<','<','<','>','>','<'},
{'>' ,'>','>','>','<','>','>','<'},
{'>','>','>','>','<','>','>','<'},
{'<','<','<','<','<','=',' ','<'},
{'>','>','>','>',' ','>','>','>'},
{'<','<','<','<','<',' ','=','<'},
{'>' ,'>','>','>','<','>','>','>'}
};
typedef struct StackChar
{
char c;
struct StackChar *next;
}*SC;
typedef struct StackFloat
{
float f;
struct StackFloat *next;
}*SF;
bool Matching(char *p)
{
int i=0,j=0;
while(*p)
{
if(*p=='(')
i++;
else if(*p==')')
j++;
p++;
}
if(i==j)
return true;
return false;
}
bool Push(SC &S,char c)
{
SC p=(SC)malloc(sizeof(StackChar));//不是sizeof(SC)
if(!p)
{
printf("分配記憶體失敗\n");
return 0;
}
p->c=c;
p->next=S;
S=p;
return 1;
}
bool Push(SF &S,float f)
{
SF p=(SF)malloc(sizeof(StackFloat));//不是sizeof(SF)
if(!p)
{
printf("記憶體分配失敗\n");
return 0;
}
p->f=f;
p->next=S;
S=p;
return 1;
}
bool Pop(SC &S,char &c)
{
if(S==NULL)
{
printf("棧空無法彈棧\n");
return 0;
}
c=S->c;
SC p;
p=S;
S=S->next;
free(p);
return 1;
}
bool Pop(SF &S,float &f)
{
if(S==NULL)
{
printf("棧空無法彈棧\n");
return 0;
}
f=S->f;
SF p;
p=S;
S=S->next;
free(p);
return 1;
}
bool GetTop(SC &S,char &c)
{
if(S==NULL)
{
printf("棧空暫無元素\n");
return 0;
}
c=S->c;
return 1;
}
bool GetTop(SF &S,float &f)
{
if(S==NULL)
{
printf("棧空暫無元素\n");
return 0;
}
f=S->f;
return 1;
}
char C[8]={'+','-','*','/','(',')','#','^'};
int Find(char x)
{
for(int i=0;i<8;i++)
{
if(x==C[i])
return i;
}
return -1;
}
char Precede(char a,char b)
{
int i=Find(a);
int j=Find(b);
return Prior[i][j];
}
float Operate(float a,char theta,float b)
{
switch(theta)
{
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
case '^': return pow(a,b);
default : return 0;
}
}
float EvaluateExpression(char *p)
{
SC Optr=NULL;
SF Oper=NULL;
Push(Optr,'#');
float f,f1,f2;
char a=*p,x;
GetTop(Optr,x);//取當前棧頂元素
while(a!='#'||x!='#')
{
if(Find(a)!=-1)
{
switch(Precede(x,a))
{
case '<':
Push(Optr,a);
a=*(++p);
break;
case '=':
Pop(Optr,x);
a=*(++p);
break;
case '>':
Pop(Oper,f2);//先退棧賦值給f2
Pop(Optr,x);
Pop(Oper,f1);//後退棧賦值給f1
Push(Oper,Operate(f1,x,f2));
break;
}
}
else if(a>='0'&&a<='9')
{
int ans=0;
while(*p>='0'&&*p<='9')
{
ans=ans*10+*p-'0';
p++;
}
Push(Oper,ans);
a=*p;
}
else
{
printf("讀入非法字元\n");
return 0;
}
GetTop(Optr,x);
}
GetTop(Oper,f);
return f;
}
int main()
{
char s[maxn];
printf("\t\t\t\t-----------------\n");
printf("\t\t\t\t **表示式求值**\n");
printf("\t\t\t\t-----------------\n");
printf("請輸入待求值表示式,以#結束:\n");
while(gets(s)!=NULL)
{
char *p=s;
if(Matching(p))
{
printf("%s\b=%g\n",s,EvaluateExpression(p));
printf("請輸入待求值表示式,以#結束:\n");
}
else
printf("表示式非法,請重新輸入,以#結束:\n");
}
}