数据结构课程设计实验报告 安徽大学

时间:2024.3.19

【实验一】

停车场管理系统

设计要求

1.问题描述

设计一个停车场管理系统,模拟停车场运作,此程序具备以下功能:

(1)若车辆到达,则显示汽车在停车场内或便道上的停车位置;

(2)若车辆离开,则显示汽车在停车场内停留的时间和应缴纳的费用(在便道上停留的时间不收费);

2.需求分析

  (1)要求以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。

  (2)要求处理的数据元素包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去时刻。

  (3)要求栈以顺序结构实现,队列以链表实现。

概要设计

1. 主界面设计

为了实现“停车管理系统”的各项功能,首先为系统设计一个含有多个菜单的主控菜单子程序,以链接系统的各项子功能,方便用户使用本系统。系统主控菜单运行界面如下:

2. 存储结构设计

本系统采用顺序栈模拟停车场管理操作,以链表队列模拟便道停车管理操作。以下是本系统中涉及的存储结构的定义:

typedef struct{

   int *base;

   int *top;

   int stacksize;

   int cartime[m];

   int chepaihao[m];

}SqStack;//栈的顺序存储表示

struct List

{

   int A[m+n]; //记录车牌号信息

   int B[m+n];//记录车辆到达时选择的车位号

   int len;//表示数组中元素个数

}L;

typedef struct QNode

{

//链队列元素结点类型

  int data;

struct QNode  *next;

}QNode, *QueuePtr;

typedef struct

{

//链队列类型

QueuePtr front;

QueuePtr rear;

}LinkQueue;

3.系统主要功能设计

本系统共采用3个功能模块,每个模块中又各自包含自己的子功能,各功能模块如下:

1.车辆到达;该模块将给用户提供两种停车选择,是场内停车还是便道停车方式,便于用户选择。

2.车辆离开;用户进入该界面,只要输入相关信息,系统将会显示用户在该停车场内停留的时间以及是否需要支付相应金额的停车费用等。

3.退出系统;方便用户退出本系统。

模块设计

1. 模块设计

本程序包含4个模块,它们分别是:主程序模块、菜单选择模块、栈操作模块、队列操作模块。调用关系如图所示:

2. 系统子程序及功能设计

1)   void Initshuzu()                     //初始化数组

2)   void time()                          //时间函数

3)   void chepaihao()                     //输入的车牌号

4)   void InitStack(SqStack &S)           //构造一个空栈s

5)   void push(SqStack &S,int e)          //车辆进入停车场场内停车

6)   void pop(SqStack &S,int e)           //车辆离开停车场场内

7)   void InitQueue(LinkQueue &Q)         //构造一个空队列Q

8)   void EnQueue(LinkQueue &Q,int elem)  //车辆进入便道

9)   void DeQueue(LinkQueue &Q ,int &e)   //车辆离开便道

10) void tingchefangshi()                //选择停车方式,场内停车还是便道停车

11) void likai()                         //车辆离开

12) void main()                          //主函数

3. 函数主要调用关系图

椭圆: 12           

                           

 

 

椭圆: 10椭圆: 11椭圆: 7椭圆: 4椭圆: 1 

 

详细设计

1.数据类型定义

(1)栈的顺序存储结构体定义

typedef struct{

   int *base;

   int *top;

   int stacksize;

   int cartime[m];

   int chepaihao[m];

}SqStack;

(2)数组的结构体定义

struct List

{

   int A[m+n]; //记录车牌号信息

   int B[m+n];//记录车辆到达时选择的车位号

   int len;//表示数组中元素个数

}L;

(3)链队列元素结点的结构体定义

typedef struct QNode

{

  int data;

struct QNode  *next;

}QNode, *QueuePtr;

typedef struct

{

QueuePtr front;

QueuePtr rear;

}LinkQueue;

(4)全局变量定义

int z;

time_t a[m+n],end;

double A[m+n]={0};

int count1=0,count2=0;//count1、count2分别用来统计场内停车数和便道停车数,并且初始化为0

2.系统主要子程序设计

(1)车辆进入停车场场内停车

void push(SqStack &S,int e)

{//车辆进入停车场场内停车

    int stacksize=50;

    if(S.top-S.base>=stacksize){//栈满,追加存储空间

       S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

       if (!S.base) exit(OVERFLOW );

       S.top=S.base+S.stacksize;

       S.stacksize +=STACKINCREMENT;

    }

    *S.top++=e;

}//push

(2)车辆进入便道停车

void EnQueue(LinkQueue &Q,int elem)

{//车辆进入便道

QNode *s;

s=(QueuePtr)malloc(sizeof(QNode));

if(!s)  exit(OVERFLOW);

s->data=elem;

s->next=NULL;

Q.rear->next=s;

Q.rear=s;

}

(3)车辆离开场内

void pop(SqStack &S,int e)

{//车辆离开停车场场内

    e=*--S.top;

}//pop

(4)车辆离开便道

void DeQueue(LinkQueue &Q ,int &e)

{//车辆离开便道

  QNode *t;

  if(Q.front==Q.rear)

  {

printf("便道内无任何车辆\n");

exit(1);

  }

  else

  {

  t=Q.front->next;

  e=t->data;

  Q.front->next=t->next;

  if(Q.rear==t) Q.rear=Q.front;

  free(t);

  }

}

(5)选择停车方式

void tingchefangshi()

{//选择停车方式,场内停车还是便道停车

    printf("                            请选择您的停车方式:\n");

    printf("                              1. 场内停车    \n");

    printf("                              2. 便道停车    \n");

    scanf("%d",&z);

    switch(z)

    {

    case 1:

       {if(count1<=m){

       printf("  您选择的是:  1. 场内停车\n");

       printf("  您的车位是:%d 号车位\n",count1);

       chepaihao();

       printf("\n");

       printf("  从现在开始为您计时,您的到达时间是:\n");

       time();

       a[count1]=time(NULL);

       count1++;

        push(S,count1);

   

       }

       else printf("  当前车位已满,请选择其他停车方式\n");

       break;

    return;

       }

    case 2:

       {if(count2<=n){

       printf("  您选择的是 2.便道停车\n");

       printf("  您的车位是:%d 号车位\n",count2+m);

       EnQueue(Q,count2);

       chepaihao();

       printf("\n");

       printf("  从现在开始为您计时,您的到达时间是:\n");

       time();

        a[count2]=time(NULL);

       count2++;

        EnQueue(Q,count2);

      

       }

       else printf("  当前车位已满,请选择其他停车方式\n");

       break;

        return;

        }

    default : printf("  您的输入有误,请重新输入!\n");

     return;

    }

getch();

}

(6)车辆离开函数

void likai()

{

    int i;

  printf("  请输入您的车位号:\n");

  scanf("%d",&i);

  if(i>=0 && i<=m)

  {

  end=time(NULL);

  A[i]=difftime(end,a[i]);

  printf("  您在停车场内停留时间为:%0.2f 秒\n",difftime(end,a[i]));

  printf("  您所需支付金额为:%0.2f 元\n",difftime(end,a[i])*j);

  printf("  感谢您的使用,欢迎下次光临!");

  count1--;

  }

  else  if(i>m && i<=m+n)

  {

  end=time(NULL);

  A[i]=difftime(end,a[i]);

  printf("  您在停车场内停留时间为:%0.2f 秒\n",difftime(end,a[i]));

  printf("  您的服务是免费服务,感谢您的使用,欢迎下次光临!");

  count1--;

  }

  else printf("  您的输入有误,请重新输入!");

}

测试分析

系统运行主界面如下:

1.  车辆到达界面

车辆到达后需要选择相应的停车方式,主要有两种方式,场内停车方式和便道停车方式。

2.  车辆离开界面

车辆离开时需要输入自己的车位号,系统会自动判别你的停车方式,提供相关服务

   

3.  车辆进入场内停车

4.  车辆进入便道停车

  

5.  车辆离开场内

   

6.  车辆离开便道

 

源程序清单

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

#include<conio.h>

#include<time.h>

#include<string.h>

#define m 50//停车场内总容纳量m,车位号依次为:1—50

#define n 50 //停车场便道容纳量n,车位号依次为:51-100

#define p 3    //车牌号码的位数000-999

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

#define OVERFLOW 0

#define T 100

int z;

time_t a[m+n],end;

double A[m+n]={0};

#define j 0.001 //停车场内收费标准0.001元/秒

int count1=0,count2=0;//count1、count2分别用来统计场内停车数和便道停车数,并且初始化为0

typedef struct{

   int *base;

   int *top;

   int stacksize;

   int cartime[m];

   int chepaihao[m];

}SqStack;//栈的顺序存储表示

struct List

{

   int A[m+n]; //记录车牌号信息

   int B[m+n];//记录车辆到达时选择的车位号

   int len;//表示数组中元素个数

}L;

typedef struct QNode

{

//链队列元素结点类型

  int data;

struct QNode  *next;

}QNode, *QueuePtr;

typedef struct

{

//链队列类型

QueuePtr front;

QueuePtr rear;

}LinkQueue;

void Initshuzu()

{//初始化数组

   for(int i=1;i<=m+n;i++)

   L.B[i]=0;

   L.len=0;

};

void time()

{//时间函数

    time_t timep;

    time (&timep);

    printf("                                现在时刻:%s",ctime(&timep));

}

void chepaihao()

{//输入的车牌号

    int ch[p];

    int i;

    printf("请输入您的车牌号:");

    for(i=0;i<3;i++)

       scanf("%d",&ch[i]);

    printf("\n");

    printf("您输入的车牌号码为:\n");

    for(i=0;i<3;i++)

    {

       printf("%d",ch[i]);

    }

}

void InitStack(SqStack &S){

//构造一个空栈s

    S.base=(int *)malloc(STACK_INIT_SIZE * sizeof(int));

    if(!S.base)exit(OVERFLOW);

    S.top=S.base;

    S.stacksize=STACK_INIT_SIZE;

}

SqStack S;

void push(SqStack &S,int e)

{//车辆进入停车场场内停车

    int stacksize=50;

    if(S.top-S.base>=stacksize){//栈满,追加存储空间

       S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

       if (!S.base) exit(OVERFLOW );

       S.top=S.base+S.stacksize;

       S.stacksize +=STACKINCREMENT;

    }

    *S.top++=e;

}//push

void pop(SqStack &S,int e)

{//车辆离开停车场场内

    e=*--S.top;

}//pop

void InitQueue(LinkQueue &Q)

{//构造一个空队列Q

Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));

if(!Q.front) exit(OVERFLOW);

Q.front->next=NULL;

}

LinkQueue Q;

void EnQueue(LinkQueue &Q,int elem)

{//车辆进入便道

QNode *s;

s=(QueuePtr)malloc(sizeof(QNode));

if(!s)  exit(OVERFLOW);

s->data=elem;

s->next=NULL;

Q.rear->next=s;

Q.rear=s;

}

void DeQueue(LinkQueue &Q ,int &e)

{//车辆离开便道

  QNode *t;

  if(Q.front==Q.rear)

  {

printf("便道内无任何车辆\n");

exit(1);

  }

  else

  {

  t=Q.front->next;

  e=t->data;

  Q.front->next=t->next;

  if(Q.rear==t) Q.rear=Q.front;

  free(t);

  }

}

void tingchefangshi()

{//选择停车方式,场内停车还是便道停车

    printf("                            请选择您的停车方式:\n");

    printf("                              1. 场内停车    \n");

    printf("                              2. 便道停车    \n");

    scanf("%d",&z);

    switch(z)

    {

    case 1:

       {if(count1<=m){

       printf("  您选择的是:  1. 场内停车\n");

       printf("  您的车位是:%d 号车位\n",count1);

       chepaihao();

       printf("\n");

       printf("  从现在开始为您计时,您的到达时间是:\n");

       time();

       a[count1]=time(NULL);

       count1++;

        push(S,count1);

   

       }

       else printf("  当前车位已满,请选择其他停车方式\n");

       break;

    return;

       }

    case 2:

       {if(count2<=n){

       printf("  您选择的是 2.便道停车\n");

       printf("  您的车位是:%d 号车位\n",count2+m);

       EnQueue(Q,count2);

       chepaihao();

       printf("\n");

       printf("  从现在开始为您计时,您的到达时间是:\n");

       time();

        a[count2]=time(NULL);

       count2++;

        EnQueue(Q,count2);

      

       }

       else printf("  当前车位已满,请选择其他停车方式\n");

       break;

        return;

        }

    default : printf("  您的输入有误,请重新输入!\n");

     return;

    }

getch();

}

void likai()

{

    int i;

  printf("  请输入您的车位号:\n");

  scanf("%d",&i);

  if(i>=0 && i<=m)

  {

  end=time(NULL);

  A[i]=difftime(end,a[i]);

  printf("  您在停车场内停留时间为:%0.2f 秒\n",difftime(end,a[i]));

  printf("  您所需支付金额为:%0.2f 元\n",difftime(end,a[i])*j);

  printf("  感谢您的使用,欢迎下次光临!");

  count1--;

  }

  else  if(i>m && i<=m+n)

  {

  end=time(NULL);

  A[i]=difftime(end,a[i]);

  printf("  您在停车场内停留时间为:%0.2f 秒\n",difftime(end,a[i]));

  printf("  您的服务是免费服务,感谢您的使用,欢迎下次光临!");

  count2--;

  }

  else printf("  您的输入有误,请重新输入!");

}

//主函数

void main()

{

system("color 1f");

system("mode con:cols=90 lines 35");

Initshuzu();

InitStack(S);

InitQueue(Q);

while(1)

{

    printf("\n ***************************** 欢迎光临ABC停车场 ***************************** \n");

    printf("\n                                                                              \n");

    printf("                                1.车辆到达\n");

    printf("                                2.车辆离开\n");

    printf("                                3.退出系统\n\n");

    time();

    printf("\n                     提示:选择后按回车键进入下一步操作\n ");

    printf("\n                                                                              \n");

    printf("\n ***************************** 欢迎光临ABC停车场 ***************************** \n");

    printf(                                 "请选择您所需服务:  ");

      int c;

      scanf("%d",&c);

         switch(c)

      {

        case 1:

            {

            system("cls");

            printf("\n ***************************** 车辆到达界面 ***************************** \n");

            tingchefangshi();

            getch();

             system("cls");

            break;

            }

        case 2:

            {

            system("cls");

            printf("\n ***************************** 车辆离开界面 ***************************** \n");

            likai();

             getch();

             system("cls");

            break;

            }

             return;

            getch();system("cls");

        case 3:

           return;

            getch();

            system("cls");

      

        default:printf("  您的输入有误!请重新输入:\n");

            getch();

            system("cls");

      

      }

}

}

用户手册

1.  本程序执行程序文件为“停车管理系统.exe”。

2.  车辆进入停车场,场内允许及便道允许停车数分别为50个车位,依次为0-49和50-99,用户可根据自己需要进行适当更改,不影响程序执行。

3.  程序中车牌号暂假定为3位,请用空格键隔开,否则将出现差错。

4.  程序内每一界面跟换需要敲两次回车键方才有效,方便用户确认录入信息是否正确无误。

实验二

重言式判别问题

设计要求

1.  问题描述

       一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。试写一个程序,通过真值表判断一个逻辑表达式属于上述哪一种类型。

2.  需求分析

(1)逻辑表达式从终端输入,长度不超过一行。逻辑运算符包括“|”、“+”、“-”,分别表示或、与、非,运算优先程度递增,但可有括号改变,即括号内的运算优先。逻辑变元为大写字母。表达式中任何地方都可以含有多个空格符。

(2)若是重言式或矛盾式,可以只显示“True Forever”或“False Forever”,否则显示“Satisfactible”以及变量名序列,与用户交互。若用户对表达式中变元取定一组值,程序就求出显示逻辑表达式的值。

概要设计

1. 主界面设计

  

2. 存储结构设计

为实现上述程序功能,应以有序链表表示集合。为此,需要抽象数据类型:栈和二叉树。

TYPE  bpointer=^bnode;
       bnode=RECORD
           data: char;
            val: boolean;
            lchild,rchild: bpointer
          END;

3. 系统功能设计

该系统主要包含三大功能:

1) 逻辑表达式的判别(不显示各种取值组合的结果) 

2) 逻辑表达式的判别(并显示各种取值组合的结果)

3) 逻辑表达式的求值(根据用户的取值)  

模块设计

1. 模块设计

该系统主要包含5个模块:

1)   主程序模块

2)   对栈的操作模块

3)   二叉树的建立模块

4)   逻辑运算符的优先级判别模块

5)   重言式的判别模块。

其调用关系如图所示

 

2. 系统子程序及功能设计

(1)  void creatzuhe(int n)//用于产生变量的各种取值组合;

(2)  void create(bitree &zigen,bitree l,bitree r)//自底向上地根据运算符的优先级来建立分子树函数;当逻辑表达式读完后-子根zigen就是一棵完整的二叉树;

(3)  char youxianji(char lie,char hang)//逻辑运算符的优先级判别;

(4)  void creatstack(sqstack &st)//对操作符栈和变量堆栈的操作;

(5)  void creattree(char s[],bitree &tree)//重言式的识别函数;

(6)  int value_tree(bitree tree)//根据变量的取值组合并利用逻辑表达式的性质对树进行求值;

(7)  void user()//用户设定变量的一种取值;

(8)  void push(sqstack &st,bitree e);

(9)  void pop(sqstack &st,bitree &e);

(10)void gettop(sqstack &st,bitree &e);

(11)void main()//主函数;

3. 函数主要调用关系

函数主要调用关系如下图所示

 


详细设计

1.数据类型定义

(1)二叉树结点定义

typedef struct btdnode{

 char data;

 struct btdnode *lchild;

 struct btdnode  *rchild;

}*bitree;

(2)表达式使用的堆栈定义

typedef struct lnode_optr{     

 struct btdnode **base;    //栈中的元素都是树的结点结构;

 struct btdnode **top;

 int stacksize;

}sqstack;

(3)全局变量及宏定义

#define stack_size_normal 100

#define bianliang_max 20

#define str_max 60

int zuhe[bianliang_max];//变量的取值组合数组定义;

int N;//变量个数;

3. 系统主要子程序设计

(1)用于产生变量的各种取值组合;

void creatzuhe(int n)

{

 int i,num=0,j=0,e;

 int temp[bianliang_max];

    for(i=0;i<N;i++)

  zuhe[i]=0;

 while(n)

 {

  e=n%2;

  num++;

  temp[j++]=e;

  n=n/2;

 }

 j=j-1;

    num=N-num;

 while(j>=0)

 {

     e=temp[j--];

  zuhe[num++]=e;

 }

}

(2)自底向上地根据运算符地优先级来建立分子树函数;当逻辑表达式读完后-子根zigen就是一棵完整的二叉树

int k=0;//建树的标志,k=1表示第一次建立分子树,要对左右孩子的指针域处理

void create(bitree &zigen,bitree l,bitree r)

{

    zigen->lchild=l;

 zigen->rchild=r;//分树的链接

 if(l&&r)

 {

     if(int(l->data)>=65&&int(l->data)<=90)

  {

  l->lchild=NULL;

  l->rchild=NULL;

  }

   if(int(r->data)>=65&&int(r->data)<=90)

   {

     r->lchild=NULL;

     r->rchild=NULL;

   }

 }

}

(3)逻辑运算符的优先级判别;

char youxianji(char lie,char hang)

{

 int    i,j;

 char bijiao[7][7]={' ','|','&','~','(',')','#',

                 '|','>','<','<','<','>','>',

                       '&','>','>','<','<','>','>',                                                                                                                                                                                                                                         

                       '~','>','>','>','<','>','>',

        '(','<','<','<','<','=',' ',

        ')','>','>','>',' ','>','>',

        '#','<','<','<','<',' ','='};

for(i=0;i<7;i++)

   if(bijiao[0][i]==lie)

    break;

for(j=0;j<7;j++)

   if(bijiao[j][0]==hang)

    break;

   return bijiao[j][i];

}

(4)对操作符栈和变量堆栈的操作;

void creatstack(sqstack &st)

{

    st.base=(bitree*)malloc(stack_size_normal*sizeof(btdnode));

 if(!st.base) exit(0);

 st.top=st.base;

 st.stacksize=stack_size_normal;

}

void push(sqstack &st,bitree e)

{

 if(st.top-st.base<st.stacksize)

 *st.top++=e;

 else exit(0);

}

void pop(sqstack &st,bitree &e)

{

 if(st.top==st.base) exit(0);

 e=*--st.top;

}

void gettop(sqstack &st,bitree &e)

{

 if(st.top==st.base) exit(0);

 e=*(st.top-1);

}

(5)重言式的识别函数;

void creattree(char s[],bitree &tree)

{

 sqstack  variable;       //变量栈;

    sqstack  logic;         //逻辑运算符栈;

    creatstack(variable);

 creatstack(logic);

 bitree logic_di,variables,logics,e,a,b,theta,kuohao;   //定义栈中的元素;

                  //theta为最后的二叉树的根;

 logic_di=(bitree)malloc(sizeof(btdnode));

 if(!logic_di)  exit(0);

 logic_di->data='#';

 push(logic,logic_di);

   while(*s!=NULL)

 {    

  if(int(*s)>=65&&int(*s)<=90)

  { 

      variables=(bitree)malloc(sizeof(btdnode));

   if(!variables)  exit(0);

   variables->data=*s;

   push(variable,variables);

    }

    else if(int(*s)>90||int(*s)<65)

    { 

      gettop(logic,e);//取运算符栈的栈顶元素进行优先级比较

     switch(youxianji(*s,e->data))

   {

   case '<': //栈顶的运算符优先级低,逻辑运算符进栈

          logics=(bitree)malloc(sizeof(btdnode));

             if(!logics)  exit(0);

             logics->data=*s;

             push(logic,logics);

          break;

            case '='://脱括号并接受下一个字符;

         pop(logic,kuohao);break;

     

   case '>':pop(logic,theta);//弹出逻辑运算符

         pop(variable,a);//弹出变量

      b=NULL;

      if(theta->data!='~')

          pop(variable,b);

      //建树的函数调用

      k=k+1;

      create(theta,b,a);

     

                     push(variable,theta);//将临时的根作为新的变量压入变量栈中;

         if(*s!='#'&&*s!=')')

      {

      logics=(bitree)malloc(sizeof(btdnode));

               if(!logics)  exit(0);

               logics->data=*s;

               push(logic,logics);

      }

      else  s=s-1;

      break;

   }

    }

   s++;

 }

 tree=theta;

}

(6)根据变量的取值组合并利用逻辑表达式的性质对树进行求值;

int value_tree(bitree tree)

{

    if(!tree) return 0;                                       //遇到空的结点;

 else if(tree->data!='|'&&tree->data!='&'&&tree->data!='~')//找到的是变量;

     return  zuhe[int(tree->data)-65];

    else if(int(tree->data)<65||int(tree->data)>90)           //找到的是运算符;

      switch(tree->data)

   {

   case '|': return(value_tree(tree->lchild)||value_tree(tree->rchild));

   case '&': return(value_tree(tree->lchild)&&value_tree(tree->rchild));

   case '~': return(!value_tree(tree->rchild));

   }

}

(7)用户设定变量的一种取值;

void user()

{

 int i;

 cout<<"请依次输入你的变元取值"<<endl;

 for(i=65;i<65+N;i++)

 {

 cout<<char(i)<<" = ";

 cin>>zuhe[i-65];

 }

}

测试分析

测试各组数据如下所示:

(1)(A|~A)&(B|~B)

(2)(A&~A)&C

(3)A|B|C|D|E~A

(4)A&B&C&~B

(5)(A|B)&(A|~B)

(6)A~B|~A&B

源程序清单

#include<stdlib.h>

#include<stdio.h>

#include<iostream.h>

#include<string.h>

#include<math.h>

#define stack_size_normal 100

#define bianliang_max 20

#define str_max 60

int zuhe[bianliang_max];//变量的取值组合数组定义;

int N;//变量个数;

typedef struct btdnode{//根据表达式建立的二叉树的结点定义;

 char data;

 struct btdnode *lchild;

 struct btdnode  *rchild;

}*bitree;

typedef struct lnode_optr{  //识别表达式使用的堆栈定义,它存放的都是树的结构;   

 struct btdnode **base;    //栈中的元素都是树的结点结构;

 struct btdnode **top;

 int stacksize;

}sqstack;

void creatzuhe(int n)

{//用于产生变量的各种取值组合;

 int i,num=0,j=0,e;

 int temp[bianliang_max];

    for(i=0;i<N;i++)

  zuhe[i]=0;

 while(n)

 {

  e=n%2;

  num++;

  temp[j++]=e;

  n=n/2;

 }

 j=j-1;

    num=N-num;

 while(j>=0)

 {

     e=temp[j--];

  zuhe[num++]=e;

 }

}

int k=0;//建树的标志,k=1表示第一次建立分子树,要对左右孩子的指针域处理

void create(bitree &zigen,bitree l,bitree r)

{//自底向上地根据运算符的优先级来建立分子树函数;当逻辑表达式读完后-子根zigen就是一棵完整的二叉树

    zigen->lchild=l;

 zigen->rchild=r;//分树的链接

 if(l&&r)

 {

     if(int(l->data)>=65&&int(l->data)<=90)

  {

  l->lchild=NULL;

  l->rchild=NULL;

  }

   if(int(r->data)>=65&&int(r->data)<=90)

   {

     r->lchild=NULL;

     r->rchild=NULL;

   }

 }

}

char youxianji(char lie,char hang)

{//逻辑运算符的优先级判别;

 int    i,j;

 char bijiao[7][7]={' ','|','&','~','(',')','#',

                 '|','>','<','<','<','>','>',

                       '&','>','>','<','<','>','>',                                                                                                                                                                                                                                        

                       '~','>','>','>','<','>','>',

        '(','<','<','<','<','=',' ',

        ')','>','>','>',' ','>','>',

        '#','<','<','<','<',' ','='};

for(i=0;i<7;i++)

   if(bijiao[0][i]==lie)

    break;

for(j=0;j<7;j++)

   if(bijiao[j][0]==hang)

    break;

   return bijiao[j][i];

}

void creatstack(sqstack &st)

{//对操作符栈和变量堆栈的操作;

    st.base=(bitree*)malloc(stack_size_normal*sizeof(btdnode));

 if(!st.base) exit(0);

 st.top=st.base;

 st.stacksize=stack_size_normal;

}

void push(sqstack &st,bitree e)

{

 if(st.top-st.base<st.stacksize)

 *st.top++=e;

 else exit(0);

}

void pop(sqstack &st,bitree &e)

{

 if(st.top==st.base) exit(0);

 e=*--st.top;

}

void gettop(sqstack &st,bitree &e)

{

 if(st.top==st.base) exit(0);

 e=*(st.top-1);

}

void creattree(char s[],bitree &tree)

{//重言式的识别函数;

 sqstack  variable;       //变量栈;

    sqstack  logic;         //逻辑运算符栈;

    creatstack(variable);

 creatstack(logic);

 bitree logic_di,variables,logics,e,a,b,theta,kuohao;   //定义栈中的元素;

                  //theta为最后的二叉树的根;

 logic_di=(bitree)malloc(sizeof(btdnode));

 if(!logic_di)  exit(0);

 logic_di->data='#';

 push(logic,logic_di);

   while(*s!=NULL)

 {    

  if(int(*s)>=65&&int(*s)<=90)

  { 

      variables=(bitree)malloc(sizeof(btdnode));

   if(!variables)  exit(0);

   variables->data=*s;

   push(variable,variables);

    }

    else if(int(*s)>90||int(*s)<65)

    { 

      gettop(logic,e);//取运算符栈的栈顶元素进行优先级比较

     switch(youxianji(*s,e->data))

   {

   case '<': //栈顶的运算符优先级低,逻辑运算符进栈

          logics=(bitree)malloc(sizeof(btdnode));

             if(!logics)  exit(0);

             logics->data=*s;

             push(logic,logics);

          break;

            case '='://脱括号并接受下一个字符;

         pop(logic,kuohao);break;

     

   case '>':pop(logic,theta);//弹出逻辑运算符

         pop(variable,a);//弹出变量

      b=NULL;

      if(theta->data!='~')

          pop(variable,b);

      //建树的函数调用

      k=k+1;

      create(theta,b,a);

     

                     push(variable,theta);//将临时的根作为新的变量压入变量栈中;

         if(*s!='#'&&*s!=')')

      {

      logics=(bitree)malloc(sizeof(btdnode));

               if(!logics)  exit(0);

               logics->data=*s;

               push(logic,logics);

      }

      else  s=s-1;

      break;

   }

    }

   s++;

 }

 tree=theta;

}

int value_tree(bitree tree)

{//根据变量的取值组合并利用逻辑表达式的性质对树进行求值

    if(!tree) return 0;                                       //遇到空的结点;

 else if(tree->data!='|'&&tree->data!='&'&&tree->data!='~')//找到的是变量;

     return  zuhe[int(tree->data)-65];

    else if(int(tree->data)<65||int(tree->data)>90)           //找到的是运算符;

      switch(tree->data)

   {

   case '|': return(value_tree(tree->lchild)||value_tree(tree->rchild));

   case '&': return(value_tree(tree->lchild)&&value_tree(tree->rchild));

   case '~': return(!value_tree(tree->rchild));

   }

}

void user()

{//用户设定变量的一种取值;

 int i;

 cout<<"请依次输入你的变元取值"<<endl;

 for(i=65;i<65+N;i++)

 {

 cout<<char(i)<<" = ";

 cin>>zuhe[i-65];

 }

}

void main()

{  //主函数

system("color 1f");

system("mode con:cols=90 lines 35");

  char str[str_max],string[str_max],*pstr;

  int loop=20,choice,i=0,choose,sum;

  bitree Tree;

 

  while(loop)

  {

  pstr=str;

  i=0;

  int  SUM=0,l;  //用于累加变量的每种组合的逻辑表达式的结果;可以作为逻辑表达式类别判别的根据

  cout<<"请输入逻辑表达式的变量的个数"<<endl;

  cin>>N;

  sum=int(pow(2,N)); //变量组合的总数;

  cout<<"请输入逻辑表达式的表达式(或用'|',与用'&'和非用'~')"<<endl;

  cin>>str;

  //重言式的正确读取;

  for(;*pstr!=NULL;pstr++)

     if(*pstr!=' ') string[i++]=*pstr;

  string[i]='#';

  string[i+1]='\0';

  cout<<"                          请选择你所需操作             "<<endl;

  cout<<"           1. 逻辑表达式的判别(不显示各种取值组合的结果) "<<endl;

  cout<<"           2. 逻辑表达式的判别(并显示各种取值组合的结果)"<<endl;

  cout<<"           3. 逻辑表达式的求值(根据用户的取值)           "<<endl;

  cout<<"请选择你所需操作: ";

  cin>>choose;

  switch(choose)

  {

  case 1://对变量的不同组合依次调用重言式二叉树的求值函数;并判别重言式的类别;

      creattree(string,Tree);//建立重言式的二叉树;

 

   for(loop=0;loop<sum;loop++)

   {

      

            creatzuhe(loop);//产生变量取值组合;

      SUM+=value_tree(Tree);

  }

  string[i]='\0';

  if(SUM==0) cout<<"逻辑表达式: "<<string<<" False forever"<<endl;

     if(SUM==sum) cout<<"逻辑表达式: "<<string<<" True forever"<<endl;

     if (SUM>0&&SUM<sum)cout<<"逻辑表达式: "<<string<<" Satisfactible"<<endl;

  break;

 case 2:creattree(string,Tree);//建立重言式的二叉树;

        cout<<"         逻辑表达式变量组合的预算结果        "<<endl;

  cout<<"---------------------------------------------"<<endl;

  printf("|       ");

  for(l=65;l<65+N;l++)

       printf("%-4c",l);

  printf("逻辑表达式的值");

  printf("              |\n");

  cout<<"---------------------------------------------"<<endl;

   for(loop=0;loop<sum;loop++)

   {

      creatzuhe(loop);//产生变量取值组合;

   SUM+=value_tree(Tree);

  

        printf("|       ");

   for(int h=0;h<N;h++)

    printf("%-4d",zuhe[h]);

 printf("%8d",value_tree(Tree));

            printf("                    |\n");

   cout<<"-------------------------------------------"<<endl;

  }

  string[i]='\0';

  if(SUM==0) cout<<"逻辑表达式: "<<string<<" False forever"<<endl;

  else if(SUM==sum) cout<<"逻辑表达式: "<<string<<" True forever"<<endl;

  else cout<<"逻辑表达式: "<<string<<" Satisfactible "<<endl;

  break;

 case 3: creattree(string,Tree);

      user();

   cout<<"逻辑表达式的值为:"<<value_tree(Tree)<<endl;

   break;

  }

  cout<<"是否继续进行运算?是按1/ 否按0:";

  cin>>choice;

  if(choice==0)

    exit(0);

  loop--;

  }

}

用户手册

用户使用本系统,需先将表达式中左右变量的总个数输入,按回车键后输入表达式,选择所需操作,即可完成对表达式的求值和判别。

更多相关推荐:
数据结构课程设计实验报告.doc

数据结构课程实验报告专业指导老师班级姓名学号完成日期一实验目的1掌握线性表的顺序存储结构和链式存储结构2熟练掌握顺序表和链表基本算法的实现3掌握利用线性表数据结构解决实际问题的方法和基本技巧4按照实验题目要求独...

数据结构课程设计实验报告

数据结构与算法课程设计报告姓名林小琼学号0907022118班级09网络工程设计时间20xx11020xx114审阅教师目录一课程设计的目的与要求含设计指标2二方案实现与调试221仓库管理系统222通讯录管理系...

数据结构课程设计实验报告格式

课程课程设计系电子信息与计算机科学系专业计算机科学与技术班级文计1111姓名毕萌玉张菁张帅学号20xx905141221011任课教师高慧学年学期20xx20xx2学期20xx年6月29日任务分配程序员张菁主要...

数据结构课程设计实验报告

软件111班18号赵庆珍数据结构课程设计任务书学期12131班级软件111一设计目的数据结构是一门实践性较强的软件基础课程为了学好这门课程必须在掌握理论知识的同时加强上机实践本课程设计的目的就是要达到理论与实际...

数据结构课程设计实验报告-

仲恺农业工程学院课程设计报告课程名称院系专业班级学号姓名指导老师计算机科学与技术计算机102班20xx10214203成筠目录题目一二算法设计包括程序流程图如函数功能入口及出口参数说明函数需求和规格说明问题描述...

《数据结构课程设计》赫夫曼编码实验报告

目录一概述1二系统分析1三概要设计2四详细设计441赫夫曼树的建立4411选择选择parent为0且权值最小的两个根结点的算法5412统计字符串中字符的种类以及各类字符的个数7413构造赫夫曼树842赫夫曼编码...

数据结构课程设计实验报告

北京理工大学珠海学院计算机学院课程设计20xx20xx学年第一学期实践教学课程名称数据结构课程实践指导教师钱峰专业班级20xx级软件工程4班教学部门计算机学院1北京理工大学珠海学院计算机学院课程设计北京理工大学...

数据结构课程设计实验报告E10914060 刘晨晨

实验一线性表逆置一问题描述分别以不同存储结构实现线性表的就地逆置线性表的就地逆置就是在原表的存储空间内将线性表a1a2a3ananan1a2a1二基本要求用顺序存储结构实现线性表的就地逆置并将结果输出三数据结构...

数据结构课程设计实验报告--177

数据结构课程设计报告姓名陈白杨班级软092老师王森玉学号099074177实验一农夫过河问题一题目农夫过河问题二问题描述从前一人农夫带着一只狼一只羊和一棵白菜注意该狼已被农夫驯服了但还是会吃羊他要将所有东西安全...

数据结构课程设计报告

XXXX大学计算机学院课程设计数据结构班级姓名学号指导教师二一一年一月二十日课程设计任务书及成绩评定课题名称校园导游咨询题目的目的和要求1设计目的巩固和加深对数据结构的理解通过上机实验调试程序加深对课本知识的理...

20xx数据结构课程设计报告

沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:树与二叉树转换院(系):专业:班级:学号:姓名:指导教师:完成日期:目录第1章题目内容与要求...11基本功能...12功能分解...1第…

数据结构课程设计报告(盐城工学院)

数据结构课程设计深度与广度优先搜索迷宫问题专班学业级号软件工程B软件1211210701128学生姓名数据结构课程设计深度与广度优先搜索迷宫问题目录1设计题目12设计分析13设计实现34测试方法341测试目的8...

数据结构课程设计实验报告(35篇)