数据结构课程设计报告-表达式求值

时间:2024.4.20

《数据结构》课程设计

表达式求值

 班级:  

学号:  

姓名:   

指导老师:

表达式求值

1、     问题描述

要求对包含加、减、乘、除、括号运算符的任意整型表达式进行求解。

2、     设计思路

这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。依次读取表达式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是‘(’而当前不是‘)’,则不需比较优先级,直接压入;如果栈顶是‘(’,当前是‘)’,则抵消(弹出‘(’,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈內时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。为了方便判断运算结束,在存储运算符之前先将‘#’压入栈1中,在输入表达式时以“#”结束,所以可以以运算符==‘#’并且栈1顶==‘#’来结束运算,弹出栈2的数值,即为表达式求值的最终结果。

上述操作的算法步骤:

(1)初始化算符S1,数字栈S2;,将‘#’压入算符栈S1中。

(2)读表达式字符=>w。

(3)当栈顶为‘#’并且w也是‘#’时结束;否则循环做下列步骤:

(3-1)如果w是数字,存储到m,再经过计算存储到num中。m=w-‘0’;num=num*pow(10,n)+m;n++;读下一个字符=>w,如果是运算符,则跳出循环;转3-2。

(3-2)w若是运算符,则:

   (3-2-1)如果栈顶为‘(’并且w为‘)’则‘(’出栈,读下一个字符=>w;转(3)。

      (3-2-2)如果栈顶为‘(’或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w;转(3)。否则:从算符栈中出栈,并从数字栈中弹出两组数字进行运算,将结果重新压入数字栈,转(3)。

3、     数据结构设计

前面提到,要用栈存储数据,由于一个数字一个运算符,所以要定义两个不同的栈,栈1的运算符为字符型;栈2的数字为浮点型,以便运算大数字。再给存储的数据个数加个上制。具体结构定义如下:

#define MAXSIZE 100

typedef struct{

char data[MAXSIZE];              /*字符型,存储运算符*/

int top;

}charSeqStack,*charPSeqStack;

typedef struct{

double data[MAXSIZE];            /*浮点型,存储数字*/

int top;

}SeqStack,*PSeqStack;

4、     功能函数设计

(1)判断操作数的函数isnum()

   判断当前所指字符是否属于数字,是就返回‘1’,不是返回‘0’。

   (2)求运算符优先级函数priority()

为了方便判断运算符优先级,先利用switch函数将不同的运算符返回不同的整型数字,再根据数字的大小判断优先级。‘+’、‘-’优先级相同,返回相同数字,‘*’、‘/’也是。

   (3)表达式求值函数infix_value()

   此函数是直接按照设计思路完成问题要求的函数,其中要调用到判断操作符的函数isnum()和求运算符优先级的函数priority()。循环结束弹出栈2的数值,并返回。

(4)主函数main()

定义一个数组存储表达式整个字符串,将返回的数值直接赋到浮点型的result,输出result。

(5)两个栈的函数设计:

栈的初始化函数charInit_SeqStack()

Init_SeqStack()

         判栈空         Empty_SeqStack()

charEmpty_SeqStack()

入栈函数      Push_SeqStack()

charPush_SeqStack()

出栈函数       Pop_SeqStack()

charPop_SeqStack()

取栈顶函数     GetTop_SeqStack()

                        charGetTop_SeqStack()

销毁栈        Destroy_SeqStack()

charDestroy_SeqStack()

5、     程序代码

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

#define MAXSIZE 100

typedef struct{

    double data[MAXSIZE];

    int top;

}SeqStack,*PSeqStack;

typedef struct{

    char data[MAXSIZE];

    int top;

}charSeqStack,*charPSeqStack;         /*定义栈,两个不同的存储类型*/

PSeqStack Init_SeqStack(void)

{

    PSeqStack S;

    S=(PSeqStack)malloc(sizeof(SeqStack));

    if(S)

       S->top=-1;

    return S;

}

charPSeqStack charInit_SeqStack(void)

{

    charPSeqStack S;

    S=(charPSeqStack)malloc(sizeof(charSeqStack));

    if(S)

       S->top=-1;

    return S;

}                                       /*栈的初始化函数*/

int Empty_SeqStack(PSeqStack S)

{

    if(S->top==-1)

       return 1;

    else

       return 0;

}

int charEmpty_SeqStack(charPSeqStack S)

{

    if(S->top==-1)

       return 1;

    else

       return 0;

}                                          /*判断栈空函数*/

int Push_SeqStack(PSeqStack S,double x)

{

    if(S->top==MAXSIZE-1)

       return 0;

    else

    {

       S->top++;

       S->data[S->top]=x;

       return 1;

    }

}

int charPush_SeqStack(charPSeqStack S,char x)

{

    if(S->top==MAXSIZE-1)

       return 0;

    else

    {

       S->top++;

       S->data[S->top]=x;

       return 1;

    }

}                                            /*入栈函数*/

int Pop_SeqStack(PSeqStack S,double *x)

{

    if(Empty_SeqStack(S))

       return 0;

    else

    {

       *x=S->data[S->top];

       S->top--;

       return 1;

    }

}

int charPop_SeqStack(charPSeqStack S,char *x)

{

    if(charEmpty_SeqStack(S))

       return 0;

    else

    {

       *x=S->data[S->top];

       S->top--;

       return 1;

    }

}                                           /*出栈函数*/

int GetTop_SeqStack(PSeqStack S,double *x)

{

    if(Empty_SeqStack(S))

       return 0;

    else

       *x=S->data[S->top];

    return 1;

}

int charGetTop_SeqStack(charPSeqStack S,char *x)

{

    if(charEmpty_SeqStack(S))

       return 0;

    else

       *x=S->data[S->top];

    return 1;

}                                            /*取栈顶函数*/

void Destroy_SeqStack(PSeqStack *S)

{

    if(*S)

       free(*S);

    *S=NULL;

    return;

}

void charDestroy_SeqStack(charPSeqStack *S)

{

    if(*S)

       free(*S);

    *S=NULL;

    return;

}                                               /*销毁栈*/

int isnum(char c)                     /*判断字符是否为操作符*/

{

    if(c>='0'&&c<='9')

       return 1;

    else

       return 0;

}

int priority(char op)                    /*求运算符的优先级*/

{

    switch(op)

    {

    case'=':return 1;

    case')':return 2;

    case'+':

    case'-':return 3;

    case'*':

    case'/':return 4;

    case'(':return 5;

    default:return 0;

    }

}

double infix_value(char *infix)           /*表达式求值函数,infix为表达式字符串*/

{

    charPSeqStack S1;

    PSeqStack S2;                    /*S1为算符栈,S2为数字栈*/

    char c,w,tope;

    double n,num,m,result,s1,s2;

    S2=Init_SeqStack();

    S1=charInit_SeqStack();             /*初始化栈*/

    if(!S1)

    {

       printf("栈初始化失败");

       return 0;

    }

    if(!S2)

    {

       printf("栈初始化失败");

       return 0;

    }

    charPush_SeqStack(S1,'#');     /*先将‘#’压入算符栈,便于判断结束*/

    w=*infix;                    /*读表达式字符*/

    while((charGetTop_SeqStack(S1,&c),c)!='#'||w!='#')

    {

       num=n=0;

       while(isnum(w))        

       {

           m=w-'0';

           num=num*pow(10,n)+m;  /*求出正确的数字*/

           w=*(++infix);

           n++;                     /*n要不断自加*/

       }

       if(n!=0)Push_SeqStack(S2,num);  /*若读过数字,则将num值压入数字栈*/

       if((charGetTop_SeqStack(S1,&c),c)=='('&&w==')')

       {

           charPop_SeqStack(S1,&tope);

           w=*(++infix);             /*两括号相遇,销毁,读下一个字符*/

       }

       else if((charGetTop_SeqStack(S1,&c),c)=='('||

              priority((charGetTop_SeqStack(S1,&c),c))<priority(w))/*比较运算符*/

       {

           charPush_SeqStack(S1,w);

           w=*(++infix);             

       }

       else

       {

           charPop_SeqStack(S1,&tope);

           Pop_SeqStack(S2,&s2);

           Pop_SeqStack(S2,&s1);

           switch(tope)

              {

                  case'+' : num=s1+s2;break;

                  case'-' : num=s1-s2;break;

                  case'*' : num=s1*s2;break;

                  case'/' : num=s1/s2;break;      /*弹出运算符的同时进行运算*/

              }

              Push_SeqStack(S2,num);       /*将运算结果重新压入栈2*/

       }

    } /*while((charGetTop_SeqStack(S1,&c),c)!='#'||w!='#')*/

    return result;

}

void main()

{

    char number[MAXSIZE];            /*存储表达式*/

    double result;                      /*表达式结果*/

    gets(number);                      /*输入表达式*/

    result=infix_value(number);

    printf("%lf\n",result);                /*输出结果*/

    getch();

}

6、     运行与测试

7、设计心得

   表达式求值是当初老师在教栈这个内容时经常提到的问题,并且也在黑板上演示过,所以在设计思想上基本已经有了框架,写起来也就方便多了,但依然也有些问题不断的出现。首先就是存运算符和数字的问题了,我不知在入栈和出栈时如何能将它们的类型合理的转化,所以只好定义两个栈,以至于这个程序看起来太“啰嗦”。在运行调试时曾遇见一个大问题,程序读不了10以上的数字,很快便找到了问题所在,在功能函数里,它每读一个数字便直接入栈,下一个若是数字便存在栈的下一个地址内了。于是我以while循环控制它何时入栈,将大数计算好了再入栈。在调试过程中还曾遇见了一个问题,就是出栈运算时将两个数字前后弄反了,应该是后出栈的-‘运算符’-前出栈的。

   写完了表达式求值使我又加深了对栈的知识与运用,也让我意识到运用栈时容易出现的错误与改善方法。虽然这个程序运行成功,但整体仍有不足,需要改善,我必须继续深入学习数据结构,以达到可以考虑程序各方面的要求改善程序。


第二篇:数据结构课程设计之表达式求值


学生课程设计

题    目: 表达式求值问题             

      姓名:   赵旺   

学  号:124090102042

所在院(系):       计算机与信息科学学院                   

专     业:      2012级计算机科学与技术                

班     级:           (2                 

指导教师:       冯韵     

20##年9月24日

一.问题描述

要求对包含加、减、乘、除、括号运算符的任意整型表达式进行求解。

二.设计思路

这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。依次读取表达式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是‘(’而当前不是‘)’,则不需比较优先级,直接压入;如果栈顶是‘(’,当前是‘)’,则抵消(弹出‘(’,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。为了方便判断运算结束,在存储运算符之前先将‘#’压入栈1中,在输入表达式时以“#”结束,所以可以以运算符==‘#’并且栈1顶==‘#’来结束运算,弹出栈2的数值,即为表达式求值的最终结果。

上述操作的算法步骤:

(1) 初始化算符S1,数字栈S2;,将‘#’压入算符栈S1中。

(2) 读表达式字符=>w。

(3) 当栈顶为‘#’并且w也是‘#’时结束;否则循环做下列步骤:

(3-1)如果w是数字,存储到m,再经过计算存储到num中。m=w-‘0’;num=num*pow(10,n)+m;n++;读下一个字符=>w,如果是运算符,则跳出循环;转3-2。

(3-2)w若是运算符,则:

   (3-2-1)如果栈顶为‘(’并且w为‘)’则‘(’出栈,读下一个字符=>w;转(3)。

     (3-2-2)如果栈顶为‘(’或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w;转(3)。否则:从算符栈中出栈,并从数字栈中弹出两组数字进行运算,将结果重新压入数字栈,转(3)。

2.1数据结构设计

前面提到,要用栈存储数据,由于一个数字一个运算符,所以要定义两个不同的栈,栈1的运算符为字符型;栈2的数字为浮点型,以便运算大数字。再给存储的数据个数加个上制。具体结构定义如下:

#define MAXSIZE 100

typedef struct{

char data[MAXSIZE];              /*字符型,存储运算符*/

int top;

}charSeqStack,*charPSeqStack;

typedef struct{

double data[MAXSIZE];            /*浮点型,存储数字*/

int top;

}SeqStack,*PSeqStack;

2.2功能函数设计

(1)判断操作数的函数isnum()

   判断当前所指字符是否属于数字,是就返回‘1’,不是返回‘0’。

   (2)求运算符优先级函数priority()

为了方便判断运算符优先级,先利用switch函数将不同的运算符返回不同的整型数字,再根据数字的大小判断优先级。‘+’、‘-’优先级相同,返回相同数字,‘*’、‘/’也是。

   (3)表达式求值函数infix_value()

   此函数是直接按照设计思路完成问题要求的函数,其中要调用到判断操作符的函数isnum()和求运算符优先级的函数priority()。循环结束弹出栈2的数值,并返回。

(4) 主函数main()

定义一个数组存储表达式整个字符串,将返回的数值直接赋到浮点型的result,输出result。

(5) 两个栈的函数设计:

栈的初始化函数charInit_SeqStack()

Init_SeqStack()

        判栈空         Empty_SeqStack()

charEmpty_SeqStack()

入栈函数      Push_SeqStack()

charPush_SeqStack()

出栈函数       Pop_SeqStack()

charPop_SeqStack()

取栈顶函数     GetTop_SeqStack()

                        charGetTop_SeqStack()

销毁栈        Destroy_SeqStack()

charDestroy_SeqStack()

三.程序代码

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

#define MAXSIZE 100

typedef struct{

   double data[MAXSIZE];

   int top;

}SeqStack,*PSeqStack;

typedef struct{

   char data[MAXSIZE];

   int top;

}charSeqStack,*charPSeqStack;         /*定义栈,两个不同的存储类型*/

PSeqStack Init_SeqStack(void)

{

   PSeqStack S;

   S=(PSeqStack)malloc(sizeof(SeqStack));

   if(S)

      S->top=-1;

   return S;

}

charPSeqStack charInit_SeqStack(void)

{

   charPSeqStack S;

   S=(charPSeqStack)malloc(sizeof(charSeqStack));

   if(S)

      S->top=-1;

   return S;

}                                       /*栈的初始化函数*/

int Empty_SeqStack(PSeqStack S)

{

   if(S->top==-1)

      return 1;

   else

      return 0;

}

int charEmpty_SeqStack(charPSeqStack S)

{

   if(S->top==-1)

      return 1;

   else

      return 0;

}                                          /*判断栈空函数*/

int Push_SeqStack(PSeqStack S,double x)

{

   if(S->top==MAXSIZE-1)

      return 0;

   else

   {

      S->top++;

      S->data[S->top]=x;

      return 1;

   }

}

int charPush_SeqStack(charPSeqStack S,char x)

{

   if(S->top==MAXSIZE-1)

      return 0;

   else

   {

      S->top++;

      S->data[S->top]=x;

      return 1;

   }

}                                            /*入栈函数*/

int Pop_SeqStack(PSeqStack S,double *x)

{

   if(Empty_SeqStack(S))

      return 0;

   else

   {

      *x=S->data[S->top];

      S->top--;

      return 1;

   }

}

int charPop_SeqStack(charPSeqStack S,char *x)

{

   if(charEmpty_SeqStack(S))

      return 0;

   else

   {

      *x=S->data[S->top];

      S->top--;

      return 1;

   }

}                                           /*出栈函数*/

int GetTop_SeqStack(PSeqStack S,double *x)

{

   if(Empty_SeqStack(S))

      return 0;

   else

      *x=S->data[S->top];

   return 1;

}

int charGetTop_SeqStack(charPSeqStack S,char *x)

{

   if(charEmpty_SeqStack(S))

      return 0;

   else

      *x=S->data[S->top];

   return 1;

}                                            /*取栈顶函数*/

void Destroy_SeqStack(PSeqStack *S)

{

   if(*S)

      free(*S);

   *S=NULL;

   return;

}

void charDestroy_SeqStack(charPSeqStack *S)

{

   if(*S)

      free(*S);

   *S=NULL;

   return;

}                                               /*销毁栈*/

int isnum(char c)                     /*判断字符是否为操作符*/

{

   if(c>='0'&&c<='9')

      return 1;

   else

      return 0;

}

int priority(char op)                    /*求运算符的优先级*/

{

   switch(op)

   {

   case'=':return 1;

   case')':return 2;

   case'+':

   case'-':return 3;

   case'*':

   case'/':return 4;

   case'(':return 5;

   default:return 0;

   }

}

double infix_value(char *infix)           /*表达式求值函数,infix为表达式字符串*/

{

   charPSeqStack S1;

   PSeqStack S2;                    /*S1为算符栈,S2为数字栈*/

   char c,w,tope;

   double n,num,m,result,s1,s2;

   S2=Init_SeqStack();

   S1=charInit_SeqStack();             /*初始化栈*/

   if(!S1)

   {

      printf("栈初始化失败");

      return 0;

   }

   if(!S2)

   {

      printf("栈初始化失败");

      return 0;

   }

   charPush_SeqStack(S1,'#');     /*先将‘#’压入算符栈,便于判断结束*/

   w=*infix;                    /*读表达式字符*/

   while((charGetTop_SeqStack(S1,&c),c)!='#'||w!='#')

   {

      num=n=0;

      while(isnum(w))        

      {

         m=w-'0';

         num=num*pow(10,n)+m;  /*求出正确的数字*/

         w=*(++infix);

         n++;                     /*n要不断自加*/

      }

      if(n!=0)Push_SeqStack(S2,num);  /*若读过数字,则将num值压入数字栈*/

      if((charGetTop_SeqStack(S1,&c),c)=='('&&w==')')

      {

         charPop_SeqStack(S1,&tope);

         w=*(++infix);             /*两括号相遇,销毁,读下一个字符*/

      }

      else if((charGetTop_SeqStack(S1,&c),c)=='('||

            priority((charGetTop_SeqStack(S1,&c),c))<priority(w))/*比较运算符*/

      {

         charPush_SeqStack(S1,w);

         w=*(++infix);             

      }

      else

      {

         charPop_SeqStack(S1,&tope);

         Pop_SeqStack(S2,&s2);

         Pop_SeqStack(S2,&s1);

         switch(tope)

            {

                case'+' : num=s1+s2;break;

                case'-' : num=s1-s2;break;

                case'*' : num=s1*s2;break;

                case'/' : num=s1/s2;break;      /*弹出运算符的同时进行运算*/

            }

            Push_SeqStack(S2,num);       /*将运算结果重新压入栈2*/

      }

   } /*while((charGetTop_SeqStack(S1,&c),c)!='#'||w!='#')*/

   return result;

}

void main()

{

   char number[MAXSIZE];            /*存储表达式*/

   double result;                      /*表达式结果*/

   gets(number);                      /*输入表达式*/

   result=infix_value(number);

   printf("%lf\n",result);                /*输出结果*/

   getch();

}

四.运行与测试

五.设计心得

   表达式求值是当初老师在教栈这个内容时经常提到的问题,并且也在黑板上演示过,所以在设计思想上基本已经有了框架,写起来也就方便多了,但依然也有些问题不断的出现。首先就是存运算符和数字的问题了,我不知在入栈和出栈时如何能将它们的类型合理的转化,所以只好定义两个栈,以至于这个程序看起来太“嗦”。在运行调试时曾遇见一个大问题,程序读不了10以上的数字,很快便找到了问题所在,在功能函数里,它每读一个数字便直接入栈,下一个若是数字便存在栈的下一个地址内了。于是我以while循环控制它何时入栈,将大数计算好了再入栈。在调试过程中还曾遇见了一个问题,就是出栈运算时将两个数字前后弄反了,应该是后出栈的-‘运算符’-前出栈的。

  

更多相关推荐:
数据结构课程设计报告模板

课程设计说明书课程名称:数据结构与算法专业:计算机科学与技术班级:103013姓名:XXX学号:03指导教师:XXX完成日期:20XX年1月12日任务书题目:黑白棋系统设计内容及要求:1.课程设计任务内容通过玩…

数据结构课程设计报告(含代码)

西安郵電學院数据结构课程设计报告题目校园导航系统院系名称计算机学院专业名称计算机科学与技术班级学生姓名学号8位指导教师设计起止时间20xx年12月11日20xx年12月15日一设计目的1通过本次课程设计巩固数据...

《数据结构课程设计报告》

安徽省巢湖学院计算机与信息工程学院课程设计报告课程名称课题名称用三元组实现稀疏矩阵的转置相加相乘专业计算机科学与技术班级学号AA姓名AAA联系方式136XXXXXXXX指导教师武彬20年月日目录1数据结构课程设...

数据结构课程设计报告

扬州大学信息工程学院数据结构课程设计报告题目井字棋小游戏班级学号姓名指导教师一课程题目井字棋小游戏二需求分析计算机和人对弈问题计算机之所以能和人对弈是因为有人将对弈的策略事先已存入计算机由于对弈的过程是在一定规...

数据结构课程设计报告(模版)

攀枝花学院学生课程设计论文题目学生姓名学号20xx108010所在院系数学与计算机学院专业计算机科学与技术专业班级20xx级计算机科学与技术1班指导教师蒋斌职称讲师20xx年12月19日数据结构课程设计任务书攀...

数据结构课程设计报告

数据结构课程设计报告撰写要求(一)纸张与页面要求1.采用国际标准A4型打印纸或复印纸,纵向打印。2.封页和页面按照下面模板书写(正文为:小四宋体1.5倍行距)。3.图表及图表标题按照模板中的表示书写。(二)课设…

数据结构课程设计报告

CENTRALSOUTHUNIVERSITY数据结构课程设计报告题目学生姓名指导教师学院专业班级完成时间交通旅游图的最短路径问题摘要数据结构主要是一门研究非数值计算的程序设计问题中的计算机操作对象以及它们之间的...

数据结构 多关键字排序课设报告

数据结构课设报告目录一设计题目2二需求分析21程序设计问题描述22基本要求23流程图2三详细设计31数据结构定义42主要算法设计53函数调用关系图84程序主要流程8四调试分析13五用户手册15六测试结果19七源...

数据结构课程设计报告

山东理工大学计算机学院课程设计数据结构计升1002班级王蕊姓名10220xx061学号肖爱梅指导教师二一一年一月二十日课程设计任务书及成绩评定课题名称建立词索引表题目的目的和要求1设计目的巩固和加深对数据结构的...

数据结构课程设计报告

淮阴工学院数据结构课程设计报告选题名称无向图应用问题系院计算机工程学院专业计算机科学与技术班级网络1111姓名1111311105指导教师周海岩单劲松学年学期20xx20xx学年第1学期年1设计任务书2摘要本课...

数据结构课程设计——报告(样例)

数据结构与算法课程设计报告王婧龚丹宋毅编写题目航空订票管理系统学期20xx秋班号学号姓名成绩哈尔滨华德学院电子与信息工程学院20xx年12月一实训设计的目的与要求注正文为宋体五号字为单倍行距一课程设计目的不少于...

数据结构课程设计报告

课程设计报告题目在n个城市之间建设网络只需保证连通即可求最经济的架设方法存储结构采用邻接表和邻接矩阵两种采用课本上的两种求解算法一需求分析11已知一个无向连通网表示n个城市以及城市间可能设置的通信网络线路其中网...

数据结构课程设计报告(34篇)