“离散数学”课程设计题目:命题公式的真值表算法专业班级学号姓名2014.11.3目录一.实验目的.......................................................2二.实验内容.......................................................21.逻辑联接词的运算..............................................................................................22.求任意一个命题公式的真值表..........................................................................3三.实验环境.......................................................3四.实验原理和实现过程(算法描述)............................31.实验原理................................................................................................................32.实验过程................................................................................................................4五.实验数据及结果分析...........................................81.题A..........................................................................................................................82.B,C题....................................................................................................................10六.源程序清单..............................................-12-1.A题部分源代码...............................................................................................-12-2.B,C题部分源代码...........................................................................................-13-七.其他收获和体会.........................................-21--1-一.实验目的;本实验课程是信息专业学生的一门专业基础课程,通过实验,帮助学生更好地掌握计算机科学技术常用的离散数学中的概念、性质和运算;通过实验提高学生编写实验报告、总结实验结果的能力;使学生具备程序设计的思想,能够独立完成简单的算法设计和分析。熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。二.实验内容;1.从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。(A)2.求任意一个命题公式的真值表(B,并根据真值表求主范式(C))详细说明:1.逻辑联接词的运算本实验要求大家利用C/C++语言,实现二元合取、析取、条件和双条件表达式的计算。充分利用联接词和逻辑运算符之间的相似性实现程序功能。2.求任意一个命题公式的真值表本实验要求大家利用C/C++语言,实现任意输入公式的真值表计算。一般我们将公式中的命题变元放在真值表的左边,将公式的结果放在真值表的右边。命题变元可用数值变量表示,合适公式的表示及求真值表转化为逻辑运算结果;可用一维数表示合式公式中所出现的n个命题变元,同时它也是一个二进制加法器的模拟器,每当在这个模拟器中产生一个二进制数时,就相当于给各个命题变元产生了一组真值指派。算法逻辑如下:(1)将二进制加法模拟器赋初值0(2)计算模拟器中所对应的一组真值指派下合式公式的真值。(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。(4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转(2)。-2-三.实验环境;采用C语言为编程语言实现。四.实验原理和实现过程(算法描述);1.实验原理(1)合取:二元命题联结词。将两个命题P、Q联结起来,构成一个新的命题P∧Q,读作P、Q的合取,也可读作P与Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P=T,Q=T时方可P∧Q=T,而P、Q只要有一为F则P∧Q=F。这样看来,P∧Q可用来表示日常用语P与Q,或P并且Q。(2)析取:二元命题联结词。将两个命题P、Q联结起来,构成一个新的命题P∨Q,读作P、Q的析取,也可读作P或Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P=F,Q=F时方可P∨Q=F,而P、Q只要有一为T则P∨Q=T。这样看来,P∨Q可用来表示日常用语P或者Q。(3)条件:二元命题联结词。将两个命题P、Q联结起来,构成一个新的命题P→Q,读作P条件Q,也可读作如果P,那么Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P=T,Q=F时方可P→Q=F,其余均为T。(4)双条件:二元命题联结词。将两个命题P、Q联结起来,构成一个新的命题P←→Q,读作P双条件于Q。这个新命题的真值与构成它的命题P、Q的真值间的关系为当两个命题变项P=T,Q=T时方可P←→Q=T,其余均为F。(5)真值表:表征逻辑事件输入和输出之间全部可能状态的表格。列出命题公式真假值的表。通常以1表示真,0表示假。命题公式的取值由组成命题公式的命题变元的取值和命题联结词决定,命题联结词的真值表给出了真假值的算法。真值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。(6)主范式:主析取范式:在含有n个命题变元的简单合取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单合取式为小项。由若干个不同的小项组成的析取式称为主析取范式;与A等价的主析取范式称为A的主析取范式。任意含n个命题变元的非永假命题公式A都存在与其等价的主析取范式,并且是惟一的。主合取范式:在含有n个命题变元的简单析取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单析取式为大项。由若-3-干个不同的大项组成的合取式称为主合取范式;与A等价的主合取范式称为A的主合取范式。任意含n个命题变元的非永真命题公式A都存在与其等价的主合取范式,并且是惟一的。2.实验过程(1)A题部分,首先是对各个输入量的处理,要确定输入的为0或1,否则则为出错,接下来就是运算处理,在C语言中本身支持的有与或非这三种,可以用!,&&,||来表示,而在这个实验中,不是与或非的可以通过转化而变为与或非的形式,具体流程图如下:开始P为1或0P为1或0运算是否继续结束YYYNNN输入P值输入Q值输出结果求合取、析取、条件和双条件的真值流程图-4-(2)B,C题部分,首先是输入一个合理的式子,然后从式子中查找出变量的个数,开辟一个二进制函数,用来生成真值表,然后用函数运算,输出结果,并根据结果归类给范式,最后输出范式。函数部分,主要是3个函数,一个为真值表递加函数,通过二进制的加法原理递进产生,一个为分级运算函数,这个函数是通过判断括号,选出最内级括号的内容执行运算函数,这样一级一级向外运算,最后得出最终结果,剩下一个为主运算函数,按照运算符号的优先级按顺序进行运算,如先将所有非运算运算完,再执行与运算。如此运算。开始输入式子计算变量个数生成真值表输出真值表变量赋值运算式子输出结果归类主范式输出主范式结束循环是否结束YN主函数-5-开始检查括号是否是最内级括号运算内容是否是最后结果返回结果结束开始结束YYNN非运算与运算或运算蕴含运算等值运算返回结果主运算函数分级运算函数-6-五.实验数据及结果分析;题A:进入界面正确运算结果-7-错误控制和输入正确后退出结果分析:这道题比较简单,主要是读取值并进行计算,同时要注意输入的值要是0或1,如果不是,则进行错误提示,并进行重新输入。-8-B,C题:欢迎界面非运算-9-与运算或运算-10-蕴含运算等值运算-11-综合运算带括号的综合运算-12-结果分析:B,C题由于本身关系比较密切,故我直接将两个做在了一起,这个程序从功能上来说,达到了题目要求的各个功能,可以运算与,或,非,蕴含,等值条件组成的表达式,并且支持括号运算,所以,总体上来说,虽然还有一些不完善的部分,但是整体是比较可以的。六.源程序清单;A题部分源代码:#includestdio.hmain(){inta[3];inti=-1,j=-1;chars;tt:printf(***************************************\n);//标语printf(****\n);printf(**欢迎进入逻辑运算软件**\n);printf(****\n);printf(***************************************\n\n);mm:printf(\n请输入P的值(0或1),以回车结束:);scanf(%d,&i);//读取P的值if(i==0||i==1);//校验输入的P值是否在允许范围内,出错则重新输入else{printf(\nP的值输入有误,请重新输入);gotomm;}nn:printf(\n请输入Q的值(0或1),以回车结束:);scanf(%d,&j);//读取Q的值if(j==0||j==1);//校验输入的Q值是否在允许范围内,出错则重新输入else{printf(\nq的值输入有误,请重新输入);gotonn;}a[0]=i&&j;//与运算a[1]=i||j;//或运算a[2]=(!i)||j;//蕴含运算,将其转化为与或非形式a[3]=((!i)||j)&&((!j)||i);//等值运算,将其转化为与或非形式printf(\n\n合取:\nP/\\Q=%d\n,a[0]);//输出结果printf(析取:\nP\\/Q=%d\n,a[1]);-13-printf(条件:\nP-Q=%d\n,a[2]);printf(双条件:\nP-Q=%d\n,a[3]);bb:printf(\n是否继续运算?(y/n));//询问是否继续操作scanf(%s,&s);if(s=='y'||s=='n'){if(s=='y'){system(cls);//清屏gotott;//返回顶层}elseprintf(欢迎下次再次使用!);//退出}else{printf(输入错误,请重新输入\n);//错误校验gotobb;}}BC题部分源代码:#includestdio.h#includestdlib.h#includestring.h#includeconio.h#includemath.h#defineN50voidpanduan(intb[N],intf);//赋值函数inttkh(charsz[N],charccu[N],inticu[N],inth0);//分级运算函数intfkh(charsz[N],charccu[N],inticu[N],inth0);//主运算函数main(){inti1,i2,d=1,icu[N],