逻辑命题公式计算

上传人:e****s 文档编号:113279240 上传时间:2022-06-24 格式:DOCX 页数:18 大小:62.01KB
收藏 版权申诉 举报 下载
逻辑命题公式计算_第1页
第1页 / 共18页
逻辑命题公式计算_第2页
第2页 / 共18页
逻辑命题公式计算_第3页
第3页 / 共18页
资源描述:

《逻辑命题公式计算》由会员分享,可在线阅读,更多相关《逻辑命题公式计算(18页珍藏版)》请在装配图网上搜索。

1、.题号:第一题题目:电梯模拟1,需求分析:计算命题演算公式的真值所谓命题演算公式是指由逻辑变量(其值为TRUE或 FALSE)和逻辑运算符(AND )、( OR)和( NOT)按一定规则所组成的公式(蕴含之类的运算可以用、和来表示)。公式运算的先后顺序为、,而括号()可以改变优先次序。已知一个命题演算公式及各变量的值,要求设计一个程序来计算公式的真值。要求:( 1)利用二叉树来计算公式的真值。首先利用堆栈将中缀形式的公式变为后缀形式;然后根据后缀形式, 从叶结点开始构造相应的二叉树; 最后按后序遍历该树, 求各子树之值,即每到达一个结点, 其子树之值已经计算出来, 当到达根结点时, 求得的值就

2、是公式之真值。( 2)逻辑变元的标识符不限于单字母,而可以是任意长的字母数字串。( 3)根据用户的要求显示表达式的真值表。2,设计:2.1 设计思想: ,数据结构设计:(1) 线性堆栈 1 的数据结构定义typedefstructDataTypestack MaxStackSize;inttop; /*当前栈的表长*/ SeqStack;用线性堆栈主要是用来存储输入的字符, 它的作用就是将中缀表达式变成后缀表达式。(2) 线性堆栈 2 的数据结构定义typedefstructBiTreeNode*stack MaxStackSize;inttop; /*当前栈的表长 */ TreeStack;

3、这个堆栈和上面的堆栈的唯一不同就是它们存储的数据的类型不同,此堆栈存储的是树节点,它的作用是将后缀表达式构成一棵二叉树。.(3) 树节点数据结构定义typedef struct NodeDataType data;struct Node *leftChild;struct Node *rightChild;BiTreeNode; 算法设计详细思路如下:首先实现将中缀表达式变成后缀表达式:在将中缀表达式变成后缀表达式的时候会用到堆栈,因此首先需要初始化一个堆栈。又由于逻辑变元可能是字符也可能是字符串,所以它又不同于将单字符的逻辑变元的中缀表达式变成后缀表达式。 我的设计是这样的, 我将中缀表达式

4、变成后缀表达式的过程分成了两部:化简(将一维的复杂的中缀表达式变成一维的简单的中缀表达式,并将字符串逻辑变元存放在二维数组中),转化(将化简后的中缀表达式变成后缀表达式)。( 1)化简: 先用一个字符数组存放输入的中缀表达式(表达式以# 号结束),然后将一维的中缀表达式中的字符串逻辑变元用一个字符进行标识,这样我们就可以将原来复杂的中缀表达式变成熟悉而又简单的中缀表达式,同时用二维数组存放那些字符串逻辑变元。实现的过程就是首先扫描一维中缀表达式,如果遇到逻辑符号, 那么记住这个逻辑符号在数组中的相对位置用一个变量存放,然后继续扫描中缀表达式直到再次遇到逻辑符号,再一次记住它在中缀表达式中的相对

5、位置,这两个逻辑符号之间的部分就是一个完整的逻辑变元,将这个字符串逻辑变元用一个字符代替并将这个字符串逻辑变元保存在二维数组中。这个过程的实现我把它放在change() 函数中。( 2)转化: 在实现该功能时,首先需要定义各符号的优先级,即:( 和 )的优先级最高; ! (逻辑非号)的优先级次之;&(逻辑与号)的优先级又低一级,| (逻辑或号)的优先级跟低; # (他不是逻辑符号,只是为了方便使用堆栈而设置)的优先级最低,接着将 # 压入堆栈。在这之后就是正式的转化了,其过程为:当读到的是逻辑变元时直接输出,并保存到保存后缀表达式的数组中,当读到的单词为运算符时,令x1 为当前栈顶运算符的变量

6、, x2 为当前扫描到的简单中缀表达式的运算符的变量,把当前读入的单词赋予变量 x2,然后比较x1 和 x2 的优先级。若x1 的优先级高于x2 的优先级,将x1 退栈作为后缀表达式的一个单词输出,然后接着比较新的栈顶运算符x1 的优先级与x2 的优先级;若 x1的优先级低于 x2的优先级,将x2 的值进栈,然后接着读下一个单词;若x1 的优先级等于x2 的优先级且 x1为“(”,x2 为“)”,将x1 退栈,然后接着读下一个单词;若x1 的优先级等于 x2 的优先级且 x1 为“# ”,x2 为“# ”,算法结束。这个过程我把它放在InToPost() 函数中。然后用后缀表达式构造出二叉树:

7、在这个过程中,我用到了之前所定义的存放树的堆栈。具体实现为:扫描后缀表达式,如果遇到逻辑变元然后将这个变元变成一个树节点,它的实现就是将该逻辑变元赋给树的data 域,然后将它的左右子树赋为NULL ,然后将这个树节点压入相应的堆栈;接着继续扫描,如果遇到的是单目运算符(非号“!”)也将它构造成一个树节点然后从堆栈里面弹出一个树形节点,将弹出的元素的作为它的左子树,右子树设置为NULL,然后将这个树节点压入相应的堆栈;如果扫描到的是双目运算符(与号“ & ”或者或号“|”)将它也构造成一棵树,然后将这个树节点压入相应的堆栈, 然后从栈中弹出两个元素, 一个作为它的左子树, 一个作为它的右子树,

8、 如此重复 n( n 为后缀表达式的长度) 次。这个过程我把它放在 Maketree() 函数中。.最后打印真值表:打印真值表也用到了前面的简单的后缀表达式,其实现的基本思想为和构造二叉树差不多, 它实现了每到一个根节点就计算一个运算的值。在打印之前需要统计字符的个数,有m 个字符则要打印2m 行,因为他有这么多情况。具体实现为:用一个字符型的数组来存放每个元素的一次取值,然后扫描后缀表达式,如果遇到逻辑变元就通过这个标识将相应的取值赋给它,然后它压入堆栈;接着继续扫描,如果遇到的是单目运算符(非号“!”)则从堆栈里面弹出一个元素,并对它进行非运算,然后又将这个运算后的值压入堆栈;如果扫描到的

9、是双目运算符(与号“ & ”或者或号“|”)则从栈中弹出两个元素,并对这两个元素进行相应的运算,然后将这个运算后的值压入堆栈,如此重复n( n 为后缀表达式的长度)次。这个过程我把它放在Print() 函数中。其中第一,二过程的流程图描述分别为:开始扫描后缀表达式扫描后缀表达式扫描到x2 是扫 描 到 的 是逻辑变元?逻辑变元?YesYesNoNo取栈顶元素 x1输出构造成树节点并进栈双目运算符单目运算符栈顶元素的优先级高?NoYes出栈小于YesNo进栈构造成树节点从栈中弹出两个元素作为其左右子树进栈构造成树节点从栈中弹出一个元素作为其左子树进栈x1 为 (,x2we 为 )x1,x2 都为

10、 #2.2 设计表示:结束.,函数调用关系及函数说明:main()change()InToPost()Maketree()Print()Precede()StackTop()StackPush1()StackPop()StackPop()StackPop1StackPush()StackPush()change() 函数原型为:void change(char prefixStr1,char prefixStr,int length,char store10,int* row,int*k )该函数含有有六个参数,其中prefixStr1 为用户输入的中缀表达式,prefixStr 为即将转化成

11、为的简单中缀表达式,length 为二维数组中存放的各个字符串的的长度store10用来存放中缀表达式中的逻辑变元,row 就是逻辑变元的个数,k 简化后的中缀表达式的长度。该函数的功能就是将复杂的中缀表达式变成简单的中缀表达式。InToPost() 函数原型为:void InToPost(char prefixStr,char postfixStr,SeqStack* myStack,int* n,int k)该函数函数有五个参数prefixStr 为中缀表达式,postfixStr 为简化后的后缀表达式,myStack 为在转化过程中用到的堆栈,n 为后缀表达式的字符长度,k 为中缀表达式

12、的字符长度。该函数的功能就是将简单的中缀表达式变成简单的后缀表达式。Maketree()函数原型为:void Maketree(BiTreeNode *root,TreeStack* myTree,char postfixStr,int n)该函数共有四个参数,其中root 为所建立的树的根节点,myTree 是在构造树时所用到的堆栈, 另外两个参数和前面的同名参数具有相同意义。 这个函数的功能就是将简单的中缀表达式变成简单的后缀表达式。Precede() 函数原型为:DataType Precede(DataType x1,DataType x2)该函数有两个参数,返回值类型为DataTyp

13、e 型,其中x1 和 x2 就是要进行优先级比较的两个两个字符。x1 为栈顶元素,x2 为扫描到的元素。该函数的功能就是比较x1 和 x2 的优先级并将比较结果返回给调用函数。Print() 函数原型为:.void Print(char postfixStr,char store10,int length,int row,int n,SeqStack* myStack)该函数有六个参数,其中 myStack 是在输出真值表过程中要用到的堆栈,其余的参数和前面介绍的函数中的同名参数具有相同的意义。该函数的功能就是打印真值表。函数接口说明:函数的调用关系在上面的图中已经显示出来了,整个程序就是由一

14、些子函数的集合,他们之间按所要实现的功能不同而调用不同的函数。在这些函数中除主函数外,其它函数的级别相同。2.3 详细设计:( 1),定义所需要的结构体,前面已经介绍了;( 2),我将中缀表达式变成后缀表达式的过程分成了两部:化简(将一维的复杂的中缀表达式变成一维的简单的中缀表达式, 并将字符串逻辑变元存放在二维数组中) ,转化(将化简后的中缀表达式变成后缀表达式)。其中化简部分将要用伪代码描述为while(prefixStr1m!=#)扫描中缀表达式while(prefixStr1m 不为运算 符 )继续扫描,直到扫描到运算符;扫描到运算符后构造简化的中缀表达式;得到这个字符串的长度;将这个

15、字符串存放在store10 中 ;转化部分用伪代码描述为:循环扫描中缀表达式if(扫描到逻辑变元)保存到后缀表达式中;elseStackTop(myStack,&x);res=Precede(x, 扫描到的运算符);if(res=)x 退栈;if(res=leftChild=x1;( 4),打印二叉树,其基本思想就是每到一个根节点就计算一个值,如此重复,直到总根节点,用伪代码简单描述为:循环赋值 if(扫描到逻辑变元 )赋值进栈;elseif(扫描到双目运算符)从栈中弹出两数对两数进行相应的运算;将运算结构进栈;;else从栈中弹出两数;对两数进行非运算;将运算结构进栈;每循环一次输出一个结构

16、;3,调试分析:. ,调试过程中遇到的问题与解决方案:这个题我个人觉的是这几个中最麻烦的一个,因为它有几个难点去分析与实现:首先就是中缀表达式中的逻辑变元不是单个字符而是一些字符串,这样在将中缀表达式转化成后缀表达式的时候就会比较麻烦,起初我也不太清楚该怎么处理他,后来经过一番分析与调试后, 我觉得用二维数组存放比较好,那样实现起来就会比较简单,当然虽然这么说,其实实现起来也还是有一定的困难的,比如怎样去找到一个完整的字符串逻辑变元,找到之后又怎样存放等等。然后再就是构造树,在构造树时要用到堆栈,但是前面用到的堆栈的数据类型和此时用到的又有很大的差别,在此时又要想到再换一个类型的堆栈,同时在构

17、造树的时候有要找到合适的算法 最后就是真值表的打印,对这一模块的实现最容易想到的就是有几个逻辑变元就进行几次循环, 每一重循环对应着一个变量的取值。但是经过分析这显然是行不通的,因为在事先我们并不知道会有多少个变元。最后我用到的方法就是那种最原始的方法,用一重循环去实现,每重循环都会有一个值,将这个值反复进行对2 取余和对2 进行整除,将取余后的值赋给相应的变元。这样总共循环2 的变元素的n 次方次即可。当然在完成这个程序时还遇到其它的很多的问题,这里就不多进行列出了,最后我在声明一下这个程序的一个缺陷, 他在进行逻辑变元数统计的时候没有对两个相同的变元进行识别。 ,算法的时空复杂度分析:本次

18、程序的完成除书上的那些头文件外,其它的算法都是自己提供,对于我自己写的那些函数,比如 change() 函数, InToPost() 函数, Print() 函数, Maketree() 函数他们的时间复杂度均为 o(n), 而对于 change() 函数其空间复杂度为 o(1), 其它的三个函数,由于他们都用到了堆栈这个数据结构他们的空间复杂度都是o(n).4,用户手册:本程序经过编译,连接后,运行时只需要用户输入一个中缀表达式,也即用户想要进行的逻辑运算的表达式。这里有三点需要要提醒用户:1,在输入表达式时“ & ”表示逻辑与;“|”号表示逻辑或,“!”表示逻辑非。在输入中缀表达式后程序将

19、自动执行并输出结构,用户不需进行干预;2,在本程序的书写中我定义了一个最多的逻辑变元的数量为十个,用户在输入表达式时应该注意输入,不要超过这个界限。3,用户在输入完所要进行运算的表达式后要记得以“ # ”号结尾,“#”号是判断输入结束的标识,如果用户没有以“ # ”号结束,那么程序的运行结果将会出错,这时用户必须重新对程序进行编译连接,然后按照要求输入表达式。5,测试数据及测试结果:.由于用户的不同输入将对应着不同的结果, 这里我仅随便输入一个逻辑表达式以供用户参考:请输入表达式(以 # 号结束 ):!aaa&(bb|cd1)&wq|d#将中缀表达式变成后缀表达式为:aaa!bbcd1|&wq

20、&d|打印构造的二叉树为:-d-|-wq-&-!-aaa-&-cd1-|-bb二叉树的后序遍历为:bbcd1|aaa!&wq&d|打印真值表为:aaabbcd1wqd运算结果000000100000010000110000001000101000011000111000000100100100010101110100001101101100011101111100000011100011010011110011001011101011.0110111110110001111001110101111101110011111011110111111111116,源程序清单:caculate.cpp

21、/ 程序源文件BiTree.h/ 树的相关操作的头文件BiTreeTraverse.h/ 树的遍历的头文件caozuo.h/ 自己提供的为实现所要求的功能而添加的头文件Compare.h/ 比较运算符优先级的头文件SeqStack.h/ 线性堆栈的有关操作的头文件TreeStack.h/ 为构造树而用到的头文件/caculate.cpp程序源文件#include #include #include #define MaxStackSize 50#include SeqStack.h#include BiTree.h#include TreeStack.h#include Compare.h#i

22、nclude BiTreeTraverse.h#include caozuo.h/void main()int i,j,n=0,k=0,row=0;SeqStack myStack;char prefixStr100,prefixStr1100;char postfixStr100;.char store1010;int length10,index=0;BiTreeNode *root;TreeStack myTree;StackInitiate(&myStack);StackPush(&myStack,#);printf( 请输入表达式 (以 # 号结束 ):);scanf(%s,pref

23、ixStr1);change(prefixStr1,prefixStr,length,store,&row,&k); /k 是中缀表达式的字符长度 InToPost(prefixStr,postfixStr,&myStack,&n,k);/printf( 将中缀表达式变成后缀表达式为:n);for(i=0;i=A & postfixStri=Z)for(j=0;jleftChild,store,length);printf(n);/打印真值表printf(n打印真值表为:n);.Print(postfixStr,store,length,row,n,&myStack);/caozuo.h头文件

24、void change(char prefixStr1,char prefixStr,int length,char store10,int* row,int* k )int j,t,m=0;char ch=A;while(prefixStr1m!=#)j=m;while(prefixStr1m!=& & prefixStr1m!=| & prefixStr1m!=! & prefixStr1m!=( & prefixStr1m!=) & prefixStr1m!=#)m+;if(m!=j)prefixStr(*k)+=ch;ch+=1;for(t=j;tm;t+)length*row=m-j

25、;store*rowt-j=prefixStr1t;(*row)+;prefixStr(*k)+=prefixStr1m;m+;if(prefixStr1m=& | prefixStr1m=| | prefixStr1m=! | prefixStr1m=( | prefixStr1m=) | prefixStr1m=#)prefixStr(*k)+=prefixStr1m;else m-;if(prefixStr1m!=#)m+;else.break;/void InToPost(char prefixStr,char postfixStr,SeqStack* myStack,int* n,i

26、nt k)int i;DataType res,x;for(i=0;i=A & prefixStri)while(res=)StackPop(myStack,&x);postfixStr(*n)+=x;StackTop(myStack,&x);res=Precede(x,prefixStri);if(res=)StackPush(myStack,prefixStri);if(res= & x=()StackPop(myStack,&x);if(res= & x=#)break;./void Print(char postfixStr,char store10,int length,int ro

27、w,int n,SeqStack* myStack)char *ptr;DataType x,v1,v2;int i,j,t,total=1;int value,value1,value2,value3;for(i=0;irow;i+)for(j=0;jlengthi;j+)printf(%c,storeij);printf();printf( 运算结果 );printf(n);for(i=0;irow;i+)total*=2;ptr=(char* )malloc(sizeof(char)*row);for(i=0;itotal;i+)t=i;for(j=0;jrow;j+)ptrj=t%2+

28、48;printf(%c,ptrj);t=t/2;for(j=0;j=A & postfixStrj=Z)value=postfixStrj-A;StackPush(myStack,ptrvalue);else.if(postfixStrj!=!)StackPop(myStack,&v1);value1=v1-48;StackPop(myStack,&v2);value2=v2-48;switch(postfixStrj)case &: value3=value1&value2; break;case |: value3=value1|value2; break;x=value3+48;Sta

29、ckPush(myStack,x);elseStackPop(myStack,&v1);value1=v1-48;value3=!value1;x=value3+48;StackPush(myStack,x);StackPop(myStack,&x);printf(%c,x);printf(n);/void Maketree(BiTreeNode *root,TreeStack* myTree,char postfixStr,int n)int i;BiTreeNode *p,*x1,*x2;for(i=0;i=A & postfixStridata=postfixStri;p-leftChi

30、ld=NULL;p-rightChild=NULL;.StackPush1(myTree,p);elsep=(BiTreeNode *)malloc(sizeof(BiTreeNode);x1=(BiTreeNode *)malloc(sizeof(BiTreeNode);x2=(BiTreeNode *)malloc(sizeof(BiTreeNode);if(postfixStri!=!)StackPop1(myTree,&x1);StackPop1(myTree,&x2);p-data=postfixStri;if(x1-data=A & x1-dataleftChild=x2;p-ri

31、ghtChild=x1;elsep-leftChild=x1;p-rightChild=x2;StackPush1(myTree,p);elseStackPop1(myTree,&x1);p-data=postfixStri;p-leftChild=x1;p-rightChild=NULL;StackPush1(myTree,p);StackPop1(myTree,&x1);root-leftChild=x1;/Compare.h头文件.DataType Precede(DataType x1,DataType x2)DataType result;switch(x2)case |:if(x1

32、=(|x1=#)result=;break;case &:if(x1=& |x1=) |x1=!)result=;elseresult=;elseresult=;break;case (:if(x1=)printf(ERROR1n);exit(0);elseresult=;break;case #:switch(x1)case #:result=;break;case (:printf(ERROR3n);exit(0);default: result=;return result;/TreeStack.h头文件typedefstructBiTreeNode*stack MaxStackSize;inttop; /*当前栈的表长*/ TreeStack;void StackInitiate1 (TreeStack *S)S-top=0;.int StackPush1 (TreeStack * S,BiTreeNode *x)if (S-top=MaxStackSize)return 0;/ 判栈满否,栈满异常退出elseS-stackS-top=x;S-top+;return 1;int StackPop1 (TreeStack * S, BiTreeNode *x)if (S-toptop-;*x=S-stackS-top;return 1;.

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!