离散数学实验报告.docx
- 文档编号:23973466
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:60
- 大小:564.41KB
离散数学实验报告.docx
《离散数学实验报告.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告.docx(60页珍藏版)》请在冰豆网上搜索。
离散数学实验报告
“离散数学”实验报告
专业:
班级:
学号:
姓名:
日期2012.12.31
一、实验课的任务、性质与目的……………………………3
二、实验目标………………………………………………3
三、实验要求………………………………………………3
四、实验内容………………………………………………3
实验一
(1)实验目标……………………………………………3
(2)实验分析……………………………………………4
(3)实验过程……………………………………………6
(4)源程序代码…………………………………………13
实验二
(1)实验目标……………………………………………20
(2)实验分析……………………………………………21
(3)实验过程……………………………………………23
(4)源程序代码…………………………………………29
实验三
(1)实验目标……………………………………………45
(2)实验分析……………………………………………45
(3)实验过程……………………………………………46
(4)源程序代码…………………………………………49
五、实验心得…………………………………………………55
一、实验课的任务、性质与目的
本实验课程是信息专业学生的一门专业基础课程,通过实验,帮助学生更好地掌握计算机科学技术常用的离散数学中的概念、性质和运算;通过实验提高学生编写实验报告、总结实验结果的能力;使学生具备程序设计的思想,能够独立完成简单的算法设计和分析。
二、实验目标
1.掌握离散数学中涉及的相关概念。
2.培养学生的逻辑思维能力和算法设计的思想。
3.熟练掌握C/C++语言程序设计的基本方法和各种调试手段。
4.熟练掌握包括数组、链表以及邻接表或邻接矩阵等数据结构的建立和运用。
5.通过实验掌握递归程序设计的基本方法。
6.掌握图的存储和遍历方法。
三、实验要求
1、实验前,复习《离散数学》课程中的有关内容。
2、上机前编好程序,上机时调试。
3、编程要独立完成,程序应加适当的注释。
4、完成实验报告。
四、实验内容
实验一
(1)实验目标
1.从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
(A)
2.求任意一个命题公式的真值表(B,并根据真值表求主范式(C))
注意:
题目类型分为A,B,C三类,其中A为基本题,完成A类题目可达到设计的基本要求,其他均为加分题,并按字母顺序分数增加越高。
(2)实验分析
1.逻辑联接词的运算
本实验要求大家利用C/C++语言,实现二元合取、析取、条件和双条件表达式的计算。
充分利用联接词和逻辑运算符之间的相似性实现程序功能。
2.求任意一个命题公式的真值表
本实验要求大家利用C/C++语言,实现任意输入公式的真值表计算。
一般我们将公式中的命题变元放在真值表的左边,将公式的结果放在真值表的右边。
命题变元可用数值变量表示,合适公式的表示及求真值表转化为逻辑运算结果;可用一维数表示合式公式中所出现的n个命题变元,同时它也是一个二进制加法器的模拟器,每当在这个模拟器中产生一个二进制数时,就相当于给各个命题变元产生了一组真值指派。
算法逻辑如下:
(1)将二进制加法模拟器赋初值0
(2)计算模拟器中所对应的一组真值指派下合式公式的真值。
(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。
(4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转
(2)。
注意,在进行表达式求值的时候,可先将带括号的中缀表达式利用栈结构转换为不带括号的后缀表达式(逆波兰式),然后进行计算。
具体方法请参考数据结构中有关“栈”的知识。
3.原理解释:
(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个命题变元的简单析取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单析取式为大项。
由若干个不同的大项组成的合取式称为主合取范式;与A等价的主合取范式称为A的主合取范式。
任意含n个命题变元的非永真命题公式A都存在与其等价的主合取范式,并且是惟一的。
(3)实验过程
(1)A题部分,首先是对各个输入量的处理,要确定输入的为0或1,否则则为出错,接下来就是运算处理,在C语言中本身支持的有与或非这三种,可以用!
&&,||来表示,而在这个实验中,不是与或非的可以通过转化而变为与或非的形式,具体流程图如下:
(2)B,C题部分,首先是输入一个合理的式子,然后从式子中查找出变量的个数,开辟一个二进制函数,用来生成真值表,然后用函数运算,输出结果,并根据结果归类给范式,最后输出范式。
函数部分,主要是3个函数,一个为真值表递加函数,通过二进制的加法原理递进产生,一个为分级运算函数,这个函数是通过判断括号,选出最内级括号的内容执行运算函数,这样一级一级向外运算,最后得出最终结果,剩下一个为主运算函数,按照运算符号的优先级按顺序进行运算,如先将所有非运算运算完,再执行与运算。
如此运算。
(3)实验界面:
主界面如下,其中显示有运算符说明及提示。
非运算结果,其中显示非运算的真值表及主范式。
与运算结果,其中与运算的真值表及主范式。
或运算结果,其中显示或运算真值表及主范式。
蕴含运算结果,其中显示蕴含运算真值表及主范式。
等值运算结果,其中显示等值运算的真值表及主范式。
综合运算,其中显示综合运算的真值表及主范式。
带括号的综合运算结果,其中显示带括号的综合运算的真值表以及主范式。
(4)源程序代码
//BC题部分源代码:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"conio.h"
#include"math.h"
#defineN50
voidpanduan(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],kh=0,jg,j=0,h0;//icu[N]用于存放变量值,kh括号计数,jg存放结果
intbj=0,hq[N],h=0,x=0,xq[N];//hq[N]存放合取结果xq[N]存放析取结果
charsz[N],ccu[N],sz0[N],s;//sz[N]存放式子,ccu[N]存放变量,sz0[N]也是用于存放式子
hq[0]=-1;
xq[0]=-1;
printf("***************************************\n");//标语
printf("****\n");
printf("**欢迎进入逻辑运算软件**\n");
printf("**(可运算真值表,主范式,支持括号)**\n");
printf("****\n");
printf("**用!
表示非**\n");
printf("**用&表示与**\n");
printf("**用|表示或**\n");
printf("**用^表示蕴含**\n");
printf("**用~表示等值**\n");
printf("****\n");
printf("***************************************\n\n");
printf("请输入一个合法的命题公式:
\n");//输入式子
gets(sz);//读取式子
strcpy(sz0,sz);//复制式子
for(i1=0;i1 { if(sz[i1]==')'||sz[i1]=='(')//存储括号数量 kh++; if(sz[i1]>='a'&&sz[i1]<='z'||sz[i1]>='A'&&sz[i1]<='Z') { for(i2=0;i2 if(ccu[i2]==sz[i1])//去除重复变量 d=0; if(d==1) { ccu[j]=sz[i1]; j++; } d=1; } } printf("\nd该式子中的变量个数为: %d\n",j);//输出变量个数 h0=j; printf("\n输出真值表如下: \n\n");//输出真值表表头 for(i1=0;i1 printf("%c",ccu[i1]); printf(""); puts(sz); printf("\n"); for(i1=0;i1 icu[i1]=0; for(i2=0;i2 printf("%d",icu[i2]); jg=tkh(sz,ccu,icu,h0);//用函数求结果 if(jg==0)//结果为0,合取加1 hq[h++]=bj; else//否则,析取加1 xq[x++]=bj; printf("%d\n",jg);//输出运算结果 strcpy(sz,sz0); for(i1=0;i1<(int)pow(2,j)-1;i1++) { ++bj; panduan(icu,j-1);//赋值变量 jg=tkh(sz,ccu,icu,h0); if(jg==0)//结果为0,合取加1 hq[h++]=bj; else//否则,析取加1 xq[x++]=bj; strcpy(sz,sz0);//恢复被修改的数组。 for(i2=0;i2 printf("%d",icu[i2]);//输出真值表前项 printf("%d\n",jg);//输出运算结果 } if(hq[0]==-1)//不存在合取范式时 printf("\n该命题公式不存在主合取范式。 \n"); else { printf("\n该命题公式的主合取范式: \n\t"); for(i1=0;i1 { if(i1>0)//判断并添加符号 printf("\\/"); printf("M(%d)",hq[i1]);//输出主合取范式 } } if(xq[0]==-1)//不存在析取范式时 printf("\n该命题公式不存在主析取范式。 \n"); else { printf("\n\n该命题公式的主析取范式: \n\t"); for(i1=0;i1 { if(i1>0)//判断并添加符号 printf("/\\"); printf("m(%d)",xq[i1]);//输出主析取范式 } } printf("\n"); printf("\n欢迎下次再次使用! \n");//结束 getch(); } voidpanduan(intb[N],intf)//二进制赋值。 { inti; i=f; if(b[f]==0)//加1 b[f]=1; else//进位 { b[f]=0; panduan(b,--i); } } inttkh(charsz[N],charccu[N],inticu[N],inth0)//分级运算函数 { inti,j,h,s,kh=0,wz[N],a; charxs1[N],ckh[N];//xs1用来保存括号内的字符ckh用来保存括号。 s=strlen(sz); for(i=0;i if(sz[i]=='('||sz[i]==')')//判断括号 { wz[kh]=i;//存储括号位置 ckh[kh]=sz[i];//存储括号类型 kh++; } if(kh==0) returnfkh(sz,ccu,icu,h0);//如果无括号,直接运行 else { for(i=0;i if(ckh[i]==')')//找到第一个) break; for(j=wz[i-1]+1,h=0;j xs1[h]=sz[j]; xs1[h]='\0'; a=fkh(xs1,ccu,icu,h0);//运行最内级括号的式子,得到结果 if(a==1)//判断并存储结果 sz[wz[i-1]]=1; else sz[wz[i-1]]=-2; for(j=wz[i-1]+1;j sz[j]=sz[j+wz[i]-wz[i-1]]; sz[j]='\0'; returntkh(sz,ccu,icu,h0);//循环执行 } } intfkh(charsz[N],charccu[N],inticu[N],inth0)//主运算函数 { inti,h=0,j=0,j1=0,j2=0,j3=0,j4=0,j5=0,i1,i2,p1=-1,p2=-1,s; chardt[N]; s=strlen(sz); if(s==1) if(sz[0]==-2)//判断是否是最后一项 return0; else return1;//1就是sz[0]的值、 else { for(i=0;i if(sz[i]=='! ') { for(i1=0;i1 if(sz[i+1]==ccu[i1])//将变量赋值并给P1 p1=icu[i1]; if(sz[i+1]==-2)//如果是前运算结果的0,则P1等于0 p1=0; if(p1==-1)//如果是数字,直接给P1 p1=sz[i+1]; dt[j+2]=! p1;//非运算 sz[i]=dt[j+2]; j++; p1=-1; for(i1=i+1;i1 sz[i1]=sz[i1+1];//将后续式子前移一项 } p1=-1; j1=j; for(i=0;i if(sz[i]=='&') { for(i1=0;i1 { if(sz[i-1]==ccu[i1])//将变量赋值并给P1 p1=icu[i1]; if(sz[i+1]==ccu[i1])//将变量赋值并给P2 p2=icu[i1]; } if(sz[i-1]==-2)//如果是前运算结果的0,则P1等于0 p1=0; if(sz[i+1]==-2)//如果是前运算结果的0,则P2等于0 p2=0; if(p1==-1)//如果是数字,直接给P1 p1=(int)(sz[i-1]); if(p2==-1)//如果是数字,直接给P2 p2=(int)(sz[i+1]); dt[j+2]=p1&&p2;//与运算 sz[i-1]=dt[j+2]; j++; j2++; p1=-1; p2=-1; for(i1=i;i1 sz[i1]=sz[i1+2]; i=i-1; } for(i=0;i if(sz[i]=='|') { for(i1=0;i1 { if(sz[i-1]==ccu[i1])//将变量赋值并给P1 p1=icu[i1]; if(sz[i+1]==ccu[i1])//将变量赋值并给P2 p2=icu[i1]; } if(sz[i-1]==-2)//如果是前运算结果的0,则P1等于0 p1=0; if(sz[i+1]==-2)//如果是前运算结果的0,则P2等于0 p2=0; if(p1==-1)//如果是数字,直接给P1 p1=sz[i-1]; if(p2==-1)//如果是数字,直接给P2 p2=sz[i+1]; dt[j+2]=p1||p2;//或运算 sz[i-1]=dt[j+2]; j++; j3++; p1=-1; p2=-1; for(i1=i;i1 sz[i1]=sz[i1+2]; i--; } for(i=0;i if(sz[i]=='^') { for(i1=0;i1 { if(sz[i-1]==ccu[i1])//将变量赋值并给P1 p1=icu[i1]; if(sz[i+1]==ccu[i1])//将变量赋值并给P2 p2=icu[i1]; } if(sz[i-1]==-2)//如果是前运算结果的0,则P1等于0 p1=0; if(sz[i+1]==-2)//如果是前运算结果的0,则P2等于0 p2=0; if(p1==-1)//如果是数字,直接给P1 p1=sz[i-1]; if(p2==-1)//如果是数字,直接给P2 p2=sz[i+1]; dt[j+2]=! p1||p2;//蕴含运算 sz[i-1]=dt[j+2]; j++; j4++; p1=-1; p2=-1; for(i1=i;i1 sz[i1]=sz[i1+2]; i--; } for(i=0;i if(sz[i]=='~') { for(i1=0;i1 { if(sz[i-1]==ccu[i1])//将变量赋值并给P1 p1=icu[i1]; if(sz[i+1]==ccu[i1])//将变量赋值并给P2 p2=icu[i1]; } if(sz[i-1]==-2)//如果是前运算结果的0,则P1等于0 p1=0; if(sz[i+1]==-2)//如果是前运算结果的0,则P2等于0 p2=0; if(p1==-1)//如果是数字,直接给P1 p1=sz[i-1]; if(p2==-1)//如果是数字,直接给P2 p2=sz[i+1]; dt[j+2]=(! p1||p2)&&(! p2||p1);//等值运算 sz[i-1]=dt[j+2]; j++; j5++; p1=-1; p2=-1; for(i1=i;i1 sz[i1]=sz[i1+2]; i--; } returndt[j+1];//返回结果 } } 2、实验二 (1)实验目标 1.求有限集上给定关系的自反、对称和传递闭包。 (有两种求解方法,只做一种为A,两种都做为B) 2.求有限集上等价关系的数目。 (有两种求解方法,只做一种为A,两种都做为B) 3.求解商集,输入集合和等价关系,求相应的商集。 (C) 注意: 题目类型分为A,B,C三类,其中A为基本题,完成A类题目可达到设计的基本要求,其他均为加分题,并按字母顺序分数增加越高。 (2)实验分析 1.求有限集上等价关系的数目。 集合上的等价关系与该集合的划分之间存在一一对应关系。 一个等价关系对应一个划分,一个划分也对应一个等价关系。 我们把n个元素的集合划分成k块的方法数叫第二类Stirling数,表示为S(n,k)。 例如有甲、乙、丙、丁四人,若所有人分成1组,只有所有人在同一组这个方法,因此S(4,1)=1;若所有人分成4组,只可以人人独立一组,因此S(4,4)=1;若分成2组,可以是甲乙一组、丙丁一组,或甲丙一组、乙丁一组,或甲丁一组、乙丙一组,或其中三人同一组另一人独立一组,即是: {A,B},{C,D} {A,C},{B,D} {A,D},{B,C} {A},{B,C,D} {B},{A,C,D} {C},{A,B,D} {D},{A,B,C} 因此S(4,2)=7。 给定S(n,n)=S(n,1)=1,有递归关系S(n,k)=S(n−1,k−1)+kS(n−1,k) 上面的递推式可以用组合证明
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 离散数学 实验 报告