离散数学实验报告.docx
- 文档编号:3285520
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:34
- 大小:698.59KB
离散数学实验报告.docx
《离散数学实验报告.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告.docx(34页珍藏版)》请在冰豆网上搜索。
离散数学实验报告
《离散数学》
实验报告
题目
专业
学号
姓名
指导教师
提交日期
实验一五种连结词的逻辑运算
一.实验目的
用C语言实现两个命题变元的合取、析取、蕴涵和等价表达式的计算。
熟悉连接词逻辑运算规则,利用程序语言实现逻辑这几种逻辑运算。
二.实验内容
从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、蕴涵和等价四种运算的的真值。
要求对输入内容进行分析,如果不符合0、1条件需要重新输入,程序有良好的输入输出界面。
三.实验过程
1.算法分析:
编程语言为c语言
合取/\:
p,q都为1的时候为1,其他为0析取\/:
p,q都为0的时候为0,其他为1
蕴含->:
p为1,q为0时为0,其他为1等价<->:
p,q同真同假
流程图
2.程序代码:
#include
intmain()
{
intp,q,i,t;
printf("************************************************\n");
printf("******\n");
printf("欢迎进入逻辑运算软件\n");
printf("******\n");
printf("************************************************\n");
do{
printf("请输入p的值(0或1)");
scanf("%d",&p);
if(p!
=0&&p!
=1)
printf("输入有误");
}while(p!
=0&&p!
=1);
do{
printf("请输入q的值(0或1)");
scanf("%d",&q);
if(q!
=0&&q!
=1)
printf("输入有误");
}while(q!
=0&&q!
=1);
do{
printf("请选择要进行的操作\n");
printf("1:
合取\n2:
析取\n3:
蕴含\n4:
等价\n");
scanf("%d",&i);
switch(i){
case1:
{
if(p&&q)printf("合取运算:
p/\q=1\n");
elseprintf("合取运算:
p/\q=0\n");
break;
}
case2:
{
if(p||q)printf("析取运算:
p\/q=1\n");
elseprintf("析取运算:
p\/q=0\n");
break;
}
case3:
{
if(p&&!
q)printf("蕴含:
p->q=0\n");
elseprintf("蕴含:
p->q=1\n");
break;}
case4:
{
if((p&&q)||(!
p&&!
q))printf("等价运算:
p<->q=1\n");
elseprintf("等价运算:
p<->q=0\n");
break;}
}printf("是否继续运算1\\0\n");
scanf("%d",&t);
}while(t);
return0;
}
3.实验数据及结果分析;
图1.初始界面
图2.输入及选择进行的操作
图3.循环操作
图4.退出程序
实验二给任意命题公式输出其真值表
一、实验目的
熟悉各命题公式,并会利用C语言编程求其真值。
二、实验内容
在菜单上输入任给一命题公式,输出其真值表
三.实验过程
1.算法分析:
算法逻辑如下:
(1)任意设计一个真值判断表达式,并使其赋值计算
(2)计算模拟器中所对应的一组真值指派下合式公式的真值。
(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。
(4)如果所输出的为真值,则页面提示“真命题”
主范式:
主析取范式:
在含有n个命题变元的简单合取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单合取式为小项。
由若干个不同的小项组成的析取式称为主析取范式;与A等价的主析取范式称为A的主析取范式。
任意含n个命题变元的非永假命题公式A都存在与其等价的主析取范式,并且是惟一的。
主合取范式:
在含有n个命题变元的简单析取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单析取式为大项。
由若干个不同的大项组成的合取式称为主合取范式;与A等价的主合取范式称为A的主合取范式。
任意含n个命题变元的非永真命题公式A都存在与其等价的主合取范式,并且是惟一的。
流程图
2.程序代码:
#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]=j+2; j++; p1=0; 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]; } for(i2=2;i2 { if(sz[i-1]==i2)//如果为前计算结果,将结果赋值并给P1 p1=dt[i2]; if(sz[i+1]==i2)//如果为前计算结果,将结果赋值并给P2 p2=dt[i2]; } 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]=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]; } for(i2=2;i2 { if(sz[i-1]==i2)//如果为前计算结果,将结果赋值并给P1 p1=dt[i2]; if(sz[i+1]==i2)//如果为前计算结果,将结果赋值并给P2 p2=dt[i2]; } 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]=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]; } for(i2=2;i2 { if(sz[i-1]==i2)//如果为前计算结果,将结果赋值并给P1 p1=dt[i2]; if(sz[i+1]==i2)//如果为前计算结果,将结果赋值并给P2 p2=dt[i2]; } 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]=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]; } for(i2=2;i2 { if(sz[i-1]==i2)//如果为前计算结果,将结果赋值并给P1 p1=dt[i2]; if(sz[i+1]==i2)//如果为前计算结果,将结果赋值并给P2 p2=dt[i2]; } 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]=j+2; j++; j5++; p1=-1; p2=-1; for(i1=i;i1 sz[i1]=sz[i1+2]; i--; } returndt[j+1];//返回结果 } } 3.实验数据及结果分析 图1.初始界面 图2.根据需要选择写出公式 实验三1、关系的闭包运算 一、实验目的 熟悉关系的闭包运算,利用C语言编程实现五种关系闭包运算算法。 二、实验内容 利用矩阵求解有限集上给定关系的自反、对称和传递闭包。 三.实验过程 1.算法分析: 在三种闭包中自反和对称闭包的求解很容易,对矩阵表示的关系,其自反闭包只要将矩阵的主对角线全部置为1就可;对称闭包则加上关系的转置矩阵(逻辑加法);传递闭包则有两种算法(二选一即可): 算法1: 直接根据 计算,过程略。 算法2: Warshall算法(1962) 设R的关系矩阵为M (1)令矩阵A=M (2)置i=1 (3)对所有的j,若A[j,i]=1,则 对于k=1,2,…,n,令A[j,k]=A[j,k]+A[i,k] 注: 此处为逻辑加,可以使用运算符|| (4)i=i+l. (5)若i≤n,则转到(3),否则结束. 流程图 2.程序代码: #include voidoutput(ints[][100]); voidzifan(ints2[][100]); voidduichen(ints2[][100]); voidchuandi2(ints2[][100]); voidchuandi1(ints2[][100]); voidaa(); ints[100][100],z; intd,n,i,j; intmain(){aa();return0;} voidaa() { printf("请输入矩阵的行数M<10\n"); scanf("%d",&n); printf("请输入矩阵的列数N<10\n"); scanf("%d",&d); printf("请输入关系矩阵\n"); for(i=0;i {printf("\n"); printf("请输入矩阵的第%d行元素",i); for(j=0;j scanf("%d",&s[i][j]); } printf("输入对应序号选择算法\n1: 自反闭包\n2: 传递闭包1\n3: 传递闭包(Warhall算法)2\n4: 对称闭包\n"); scanf("%d",&z); switch(z) { case1: zifan(s);break; case2: chuandi1(s);break; case3: chuandi2(s);break; case4: duichen(s);break; } } voidoutput(ints[][100]) {printf("所求关系矩阵为\n"); for(i=0;i {for(j=0;j printf("%d",s[i][j]); printf("\n"); } } voidzifan(ints2[][100]) { for(i=0;i s2[
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 离散数学 实验 报告