您的位置:首页 > 其它

利用栈来实现计算表达式的自动计算(二)

2009-11-15 16:14 253 查看
一、扫描一遍出结果的算法设置:
(1):设置两个栈,一个运算符栈,一个操作数栈。初始化后将"#"压入操作符栈中。
(2):顺序扫描,当输入为操作数时就将其压入操作数栈。
(3):当输入为运算符时,则比较输入运算符和运算符栈的栈顶运算符的优先级的大小。若输入运算符的优先级高于运算符栈栈顶运算符的优先级时,则将其输入到运算符栈;若运算符栈栈顶运算符的优先级高于输入运算符的优先级,则将栈中的运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;然后重新比较输入运算符和更新后的栈顶运算符的优先级的大小。
(4):当输入运算符为"("时,将"("直接入运算符栈。
(5):当输入运算符为")"时,将运算符栈栈顶运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;重复此操作直至运算符栈的栈顶元素为"(",并将"("弹出并抛弃。
(6):当扫描到"#"时,说明算术表达式已经扫描完毕,运算符栈依次出栈并从操作数栈中弹出两个操作数施以运算,将运算结果作为新的操作数输出到操作数栈,直至运算符栈栈顶为"#"时结束。
(7):最后操作数栈的栈顶元素即为运算结果,将其输出到屏幕。
对于优先级的比较,如果是同种运算符,那么在栈内的运算符的优先级就比在栈外的运算符的优先级大一;不同级的运算符它们的优先级大小按原来的大小排列

二、扫描一遍出结果的源代码:

#include <stdio.h>

#define StackSize 100

/*定义字符栈*/

typedef char ElemType;

typedef struct

{

     ElemType  data[StackSize];

     int top;

}SqStack;

/*定义数值栈*/

typedef struct

{

      double  data[StackSize];

      int top;

}dstack;

/*初始化数值栈*/

void  DsInit(dstack *s)

{

  s->top=-1;

}

/*压入数值栈*/

int Dpush(dstack *s,double e)

{

  if(s->top<StackSize-1)

  {

     s->top=s->top+1;

     s->data[s->top]=e;

     return 1;

  }

  else

  {

     return 0;

  }

}

/*出数值栈*/

double Dpop(dstack *s)

{

  double e;

  if(-1==s->top)

  {

     return 1;

  }

  else

  {

     e=s->data[s->top];/*出栈*/

     (s->top)--;

     return e;

  }

}

/*初始化字符栈操作*/

void  InitStack(SqStack *s)

{

    s->top=-1;

}

/*压入字符栈操作*/

int push(SqStack *s,ElemType e)

{

    if(s->top<StackSize-1)

    {

        s->top=s->top+1;

        s->data[s->top]=e;

        return 1;

    }

    else

    {

        return 0;

    }

}

/*出字符栈操作*/

ElemType pop(SqStack *s)

{

    ElemType e;

    if(-1==s->top)

    {

        return 1;

    }

    else

    {

        e=s->data[s->top];

        (s->top)--;

        return e;

    }

}

/*取栈顶操作*/

int GetTop(SqStack s,ElemType *e)

{

    if (0==s.top)

    {

          *e=s.data[s.top];

        return 0;

    }

    else

    {

        *e=s.data[s.top];

        return 1;

    }

}

/* 比较优先级 */

int Get_Pri(int mode,char oper)

{/* 返回运算符oper代表优先级得整数值,mode为1,表示oper是栈顶运算符,否则是当前运算符 */

    int tmp;

    switch(oper)

    {

    case '#': tmp=0;break;

    case '(': tmp=(mode? 1:6);break;

    case '+':

    case '-': tmp=(mode? 3:2);break;

    case '*':

    case '%':

    case '/': tmp=(mode? 5:4);break;

    case ')': tmp=(mode? 7:1);break;

    }

    return tmp;

}

char precede(char w,char ch)

{/* 判定运算符栈的栈顶运算符w,与当前运算符ch之间的优先关系 */

    /* 取得栈顶运算符与当前运算符得优先级 */

    int grade;

    grade=Get_Pri(1,w)-Get_Pri(0,ch);

    if(grade>0)

        return '>';

    else

    {

        if(grade==0)

            return '=';

        else

            return '<';

    }

}

/*用于计算的函数*/

void  jisuan(char s,dstack *ds)

{

    double ch;

    switch(s)

    {

        case '+':

            ch=Dpop(ds);ch+=Dpop(ds);Dpush(ds,ch);

            break;

        case '-':

            ch=Dpop(ds);ch=Dpop(ds)-ch;Dpush(ds,ch);

            break;

        case '*':

            ch = Dpop(ds);ch *= Dpop(ds);Dpush(ds,ch);

                        break;

        case '/':

                       ch = Dpop(ds);ch = Dpop(ds) / ch;Dpush(ds,ch);

                       break;

        case '%':

                       ch = Dpop(ds);ch = (double)((int)Dpop(ds)%(int)ch);

               Dpush(ds,ch);

               break;

    }

}

/*扫描算术表达式的函数*/

double comp(char arr[])

{

SqStack s1;

dstack s2;

char ch,w='/0';

int i=0;

double x=0,d=1;

InitStack(&s1);

DsInit(&s2);

push(&s1,'#');

ch=arr[i];

while(ch!='#')

{

         if('0'<=ch && ch<='9')

         {

         if('0'<=ch && ch<='9')

         {

                   while('0'<=ch && ch<='9')

                   {

                            x=x*10+(ch-'0');

                             i=i+1;

                             ch=arr[i];

                   }

                   if(ch=='.')

                     {

                             ch=arr[++i];

             while('0'<=ch && ch<='9')

                             {

                  d=d*10;

                x=x+(ch-'0')/d;

                ch=arr[++i];

                             }

                   }

                  

         }

         Dpush(&s2,x);

         x=0;

d=1;

         }

/*扫描到运算运算符的处理程序*/

if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%'||ch=='('||ch==')'||ch=='#')

{ GetTop(s1,&w);

 while(precede(w,ch)=='>')

       {

         jisuan(pop(&s1),&s2);

          GetTop(s1,&w);

        }

        if (precede(w,ch)=='<')

            push(&s1,ch);

        else

        {

          if (precede(w,ch)=='='&& ch!='#')

                pop(&s1);

        }

                   ch=(ch!='#') ? arr[++i] : ch;

}

 

}

GetTop(s1,&w);

while(w!='#')

{

         jisuan(pop(&s1),&s2);

    GetTop(s1,&w);

}

return Dpop(&s2);

}

/*主函数*/

void main()

{

    char str[100];

    char *yzh;

    printf("Please input the infix express with a '#' in the end :");/*输入表达式并以#号结束*/

    gets(str);

    yzh=str;

    printf("The infix express is:%s/n",yzh);

    printf("/nThe result is:%f/n/n",comp(str));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  express struct input 算法