大二上学期学习了数据结构,书上又一道例题是关于利用栈,实现表达式求值的问题,但是书上的代码只能实现一位数的求值,原因式在字符串中,一个数字占一个字符位置,所以每次提取数值时,只能提取一个数字,若两个数字连在一起则会出错,我又在原来的基础上,写了一个提取函数,每当遇见非运算符时,就调用这个函数,实现了实数的表达式求值。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct StackNode
{ char datac;
struct StackNode *next;
}Sqstack1;
typedef struct sqnode
{
double datai;
struct sqnode *next;
}Sqstack2;
Sqstack1* InitStack1(Sqstack1 *s)
{ s=NULL;
return s;
}
Sqstack2* InitStack2(Sqstack2 *s)
{ s=NULL;
return s;
}
Sqstack1* push1(Sqstack1 *s, char x)//运算符入栈
{ Sqstack1 *p;
p=(Sqstack1 *)malloc(sizeof(Sqstack1));
if(!p)
printf("shibai");
p->datac=x;
p->next=s;
s=p;
return s;
}
Sqstack2* push(Sqstack2 *s,double e)//数值入栈
{ Sqstack2 *p;
p=(Sqstack2 *)malloc(sizeof(Sqstack2));
if(!p)
printf("shibai");
p->datai=e;
p->next=s;
s=p;
return s;
}
Sqstack1* pop1 (Sqstack1* s,char *x)//运算符弹栈
{
if(s==NULL)
return NULL;
else
{ *x=s->datac;
Sqstack1 *p;p=s;
s=s->next;
free(p);
return s;}
}
Sqstack2* pop2(Sqstack2* s,double *x)//数值弹栈
{
if(s==NULL)
return NULL;
else
{ *x=s->datai;
Sqstack2 *p;p=s;
s=s->next;
free(p);
return s;}
}
char backc1(Sqstack1* s)//显示栈顶元素
{ if(s==NULL) printf("kong");
else
return s->datac;
}
double backc2(Sqstack2* s)//返回栈顶元素
{ if(s==NULL) printf("kong");
else
return s->datai;
}
char precede(/*栈顶*/char e,/*输入*/char y)
{ char c;
switch(e)
{ case '+':
case '-':
switch(y)
{ case '+':
case '-':
case ')':
case '#':
c='>';
break;
case '*':
case '/':
case '(':
c='<';
break;
}
break;
case '*':
case '/':
if(y=='(')
c='<';
else
c='>';
break;
case '(':
if(y==')')
c='=';
else
c='<';
break;
case ')':
c='>';
break;
case '#':
if(y=='#')
c='=';
else
c='<';
}
return c;
}
double oprat(double *x,double *y,char *c)
{ if(*c=='+')
{
return *x+*y;
}
if(*c=='-')
{
return *y-*x;
}
if(*c=='*')
{
return (*x)*(*y);
}
if(*c=='/')
{
return (*y)/(*x);
}
}
int isnum (char e)//确认是数字
{
return e<='9'&&e>='0';
}
double tiqudata(char *str,int e)
{int i=e,j=0,l=strlen(str);
char s[10];
while(isnum(str[i])||str[i]=='.')
{ s[j]=str[i];
j++;
i++;
}
int n,q=1;
double k=0;
for(i=0;i<j;i++)
{if(s[i]=='.')
{n=i;break;}
else
n=j;
}
for(i=n-1;i>=0;i--)
{ k=k+(s[i]-'0')*q;
q=q*10;
}
double p=0.1;
if(n!=j)
{ for(i=n+1;i<j;i++)
{k=k+(s[i]-'0')*p;
p=p*0.1;}
}
return k;
}
int main()
{ Sqstack2 *s2;Sqstack1 *s1;char str[20];
s1=(Sqstack1 *)malloc(sizeof(Sqstack1));
s2=(Sqstack2 *)malloc(sizeof(Sqstack2));
s2=InitStack2(s2);s1=InitStack1(s1);
gets(str);
int i=0;char k,l;
double z;
s1=push1(s1,'#');
while(str[i]!='#')
{ char *c,*g;double *x,*y;
g=(char *)malloc(sizeof(char));
y=(double *)malloc(sizeof(double));
x=(double *)malloc(sizeof(double));
c=(char *)malloc(sizeof(char));
if(isnum(str[i]))
{ z=tiqudata(str,i);
while(isnum(str[i])||str[i]=='.'){
i++;
}
s2=push(s2,z);
}
else
{ l=backc1(s1);
k=precede(l,str[i]);
switch(k)
{ case '<':
s1=push1(s1,str[i]);
i++;
break;
case '>':
s1=pop1(s1,c);
s2=pop2(s2,x);
s2=pop2(s2,y);
z=oprat(x,y,c);
s2=push(s2,z);
break;
case '=':
s1=pop1(s1,g);
i++;
break;
}
}
free(x);free(y);free(c); free(g);
}
char *c;double *x,*y;
y=(double*)malloc(sizeof(double));
x=(double *)malloc(sizeof(double));
c=(char *)malloc(sizeof(char));
while(backc1(s1)!='#')
{ s1=pop1(s1,c);
s2=pop2(s2,x);
s2=pop2(s2,y);
z=oprat(x,y,c);
s2=push(s2,z);
}
free(x);free(y);free(c);
printf("%.2lf",s2->datai);
return 0;
}
//6.5+(7.5+2.5)*3#