注册 登录
编程论坛 数据结构与算法

求教表达式求值

发布于 2010-04-28 18:38, 611 次点击
程序代码:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
#include<stdio.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

#define OVERFLOW -2
#define  OK 1
#define  TURE 1
#define  Error 0

typedef char ElemType;   
typedef ElemType OperandType;   /*操作数*/
typedef char OperatorType;


typedef struct
{  float *top;
    float *base;
    int stacksize;
}Sqstack;

typedef struct
{  char *top;
   char *base;
    int stacksize;
}SSqstack;

char OP[8]={'+','-','*','/','(',')','#','\0'};
int m[7][7]={1,1,2,2,2,1,1,


       1,1,2,2,2,1,1,

    1,1,1,1,2,1,1,
    1,1,1,1,2,1,1,
    2,2,2,2,2,0,-1,
    1,1,1,1,-1,1,1,
    2,2,2,2,2,-1,0};/*1 >  2 <  0 =  -1 不存在*/

void initstack(Sqstack *S)
{ S->base=(float *)malloc(STACK_INIT_SIZE*sizeof (float));
    if(!S->base)exit(OVERFLOW);
    S->top=S->base;
    S->stacksize=STACK_INIT_SIZE;

}

void Initstack(SSqstack *M)
{ M->base=(char)malloc(STACK_INIT_SIZE*sizeof (char));
    if(!M->base)exit(OVERFLOW);
    M->top=M->base;
    M->stacksize=STACK_INIT_SIZE;

}


void push(Sqstack *S,float n)
{
    if(S->top-S->base>=S->stacksize)
    {
      S->base=(float *)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(float));
        if(!S->base)exit(OVERFLOW);
        S->top=S->base+S->stacksize;
        S->stacksize+=STACKINCREMENT;
    }
    *S->top++=n;

}

void Push(SSqstack *M,char e)
{
    if(M->top-M->base>=M->stacksize)
    {
      M->base=(char *)realloc(M->base,(M->stacksize+STACKINCREMENT)*sizeof(char));
        if(!M->base)exit(OVERFLOW);
        M->top=M->base+M->stacksize;
        M->stacksize+=STACKINCREMENT;
    }
    *M->top++=e;

}

char pop(Sqstack *S,float n)
{
    if(S->top==S->base)
        return Error;
    n=*--S->top;
     return n;
}

char Pop(SSqstack *M,char e)
{
    if(M->top==M->base)
        return Error;
    e=*--M->top;
     return e;
}

char Gettop(SSqstack *M)
{   char e;
   if(M->top==M->base)
        return Error;
   e=*(M->top-1);
    return e;
}

float gettop(Sqstack *S)
{  float e;
   if(S->top==S->base)
        return Error;
   e=*(S->top-1);
   return e;
}

char In(char c)
{

 if(c>=35 && c<=47)
  return 1;

 else return 0;
}

char Precede(char i,char j,char *OP)
{

 int a,b; char *p;

 for(p=OP,a=0;*p!='\0';p++,a++)
  if(*p==i) break;

 for(p=OP,b=0;*p!='\0';p++,b++)
  if(*p==j) break;
  if(m[a][b]==1) return '>';
  else if(m[a][b]==2) return '<';
  else if(m[a][b]==0) return '=';

}

char Operate(char a,char theta,char b)
{

 if(a>47) a=atoi(&a);

 if(b>47) b=atoi(&b);

 switch(theta)

 {

 case '+': return a+b;
    break;

 case '-': return a-b;
   break;

 case '*': return a*b;
   break;

 case '/': return a/b;
   break;

 }
}

float EvaluateExpression(Sqstack *S,SSqstack *M)
{


 OperandType a,b,c; OperatorType theta;

 Initstack(M); Push(M,'#');

 initstack(S); c=getchar();

 while (c!='#' || Gettop(M)!='#')

 {
  if (!In(c)){push(S,c);c=getchar();}
  else
   switch(Precede(Gettop(M),c,OP))
  {
   case '<' :
    Push(M,c); c = getchar();
    break;
   case '=' :
    Pop(M,c); c = getchar();
    break;
   case '>' :
    Pop(M,theta);
    pop(S,b); pop(M,a);
    push(S,Operate(a,theta,b));
    break;
  }

 }

 return gettop(S);
}

void main()
{

 float a;

 Sqstack S;

 SSqstack M;

 printf("(ENd with #)\n");

 printf("Enter:\n");


 a=(float)EvaluateExpression(S,M);

 printf("%d",a);

 getch();
}
用栈写的表达式求值,例如:5+6*(9-3)-9/3进行求值 当输入#时结束
望高手看一下  帮忙修改一下
5 回复
#2
2010-04-28 23:41
大致看了下楼主的代码,感觉楼主像是学完了线性表,刚刚接触栈和队列,许多地方都编得很繁琐。还有一些变量上设定的太循规蹈矩。
下面的是我的代码,有空我们好好讨论一下,最近我也在研究表达式求值问题。
#3
2010-04-29 01:10
要求操作数在0-9之间,只能进行‘+’、‘-’、‘*’、‘/’四种基本运算,表达式所得结果在0-9之间,但并不难推广到更复杂的表达式求值问题。
代码如下:
#include <stdio.h>
#define MAXSIZE 100

typedef char ElemType;
typedef struct stack
{
 ElemType data[MAXSIZE];
 int top;
}SqStack;

void InitStack(SqStack *S)
{
 S->top=-1;
}

ElemType GetTop(SqStack S)
{
 if(S.top==-1) { printf("Error");exit(0); }
  else return S.data[S.top];
}

void Pop(SqStack *S)
{
 if(S->top==-1) { printf("Error");exit(0); }
  else S->top--;
}

void Push(SqStack *S,ElemType x)
{
 S->top++;
 S->data[S->top]=x;
}

int CtoD(ElemType x)
{
 return x-'0';
}

ElemType DtoC(int x)
{
 return x+48;
}

ElemType Operation(ElemType x,ElemType w,ElemType y)
{
 int i,j;
 ElemType z;
 i=CtoD(x);j=CtoD(y);
 if(w=='+') i=i+j;
 if(w=='-') i=i-j;
 if(w=='*') i=i*j;
 if(w=='/') i=i/j;
 z=DtoC(i);
 return z;
}

ElemType Precede(ElemType x,ElemType y)
{
 switch(x)
 {
  case'+':case'-':
  { if(y=='+'||y=='-'||y==')'||y=='#') return '>';
     else return '<'; }
  case'*':case'/':
  { if(y=='*'||y=='/'||y=='+'||y=='-'||y==')'||y=='#') return '>';
    else return '<'; }
  case'(':
  { if(y==')') return '=';
     else return '<'; }
  case'#': return '<';
  }
}

ElemType Value(SqStack OPND,SqStack OPTR)
{
 ElemType x,y,a,b,c;
 x=getchar();
 while(x!='#'||GetTop(OPTR)!='#')
 {
  switch(x)
  {
   case'1':case'2':case'3':case'4':case'5':
   case'6':case'7':case'8':case'9':
   { Push(&OPND,x);x=getchar();break;}
   case'+':case'-':case'*':case'/':case')':case'(':case'#':
   {  y=Precede(GetTop(OPTR),x);
      if(y=='=')  { Pop(&OPTR); x=getchar();break; }
       else if(y=='<') { Push(&OPTR,x);x=getchar();break; }
        else
           {
               c=GetTop(OPTR);Pop(&OPTR);
               a=GetTop(OPND);Pop(&OPND);
               b=GetTop(OPND);Pop(&OPND);
               Push(&OPND,Operation(b,c,a));
              }
    }
   }
  }
 return GetTop(OPND);
}

void main()
{
 SqStack OPND,OPTR;
 ElemType x;
 InitStack(&OPND);
 InitStack(&OPTR);
 Push(&OPTR,'#');
 x=Value(OPND,OPTR);
 printf("%c",x);
 getch();
}
#4
2010-04-29 12:33
回复 2楼 LegendofMine
呵呵  你是 哪的 你也在学数据结构吧  
#5
2010-04-29 22:13
回复 4楼 呜呼哀哉
恩那,呵呵,我是东北林大的,接触数据结构两个月了。
#6
2010-04-30 22:01
回复 5楼 LegendofMine
哈,差不多
1