利用栈实现表达式求值C语言版

大二上学期学习了数据结构,书上又一道例题是关于利用栈,实现表达式求值的问题,但是书上的代码只能实现一位数的求值,原因式在字符串中,一个数字占一个字符位置,所以每次提取数值时,只能提取一个数字,若两个数字连在一起则会出错,我又在原来的基础上,写了一个提取函数,每当遇见非运算符时,就调用这个函数,实现了实数的表达式求值。
代码:

#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#
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值