离散实验报告实例.docx
《离散实验报告实例.docx》由会员分享,可在线阅读,更多相关《离散实验报告实例.docx(23页珍藏版)》请在冰豆网上搜索。
离散实验报告实例
离散数学实验报告
专业计算机
班级5班
学号E01114299
姓名杨建
日期2012-12-21
所属团队:
组长杨建
成员杨建黄有伟王晓峰
成员陈明师刘云飞
工作描述
组长:
杨建,负责编写源程序及第一期编译工作;
组员:
黄有伟、王晓峰,负责第二期编译及后期软件调试;
组员:
刘云飞、陈明师,负责本实验后期总结及实验报告汇总美化工作。
组员评分---平均分(满分10分)
组长:
杨建9.1分
组员:
黄有伟8.8分
王晓峰8.7分
陈明师8.7分
刘云飞8.6分
一、实验目的
1.本实验课程是计算机专业学生的专业核心课程,通过实验,帮助学生更好地掌握计算机科学技术常用的离散数学中的概念、性质和运算;通过实验提高学生编写实验报告、总结实验结果的能力;使学生具备程序设计的思想,能够独立完成简单的算法设计和分析。
2.熟悉掌握命题逻辑中的联接词、真值表、主范式,笛卡尔乘积等概念,进一步能用它们来解决实际问题。
二、实验内容
1.命题公式真值表自动生成系统
(1)内容:
设计一个自动生成命题公式真值表的系统;简述命题逻辑的应用背景,介绍命题公式真值表的有关概念,写出生成命题公式真值表的算法及代码。
(2)要求:
简述命题逻辑的基本概念及应用背景;
设计生成命题公式真值表的算法;
写出算法的代码,在计算机上实现生成命题公式真值表的功能;
任给一个命题公式,系统可自动生成该公式的真值表。
2.命题公式主析(合)取范式自动生成系统
(1)内容:
设计一个自动生成命题公式主析(合)取范式的系统;简述命题逻辑的应用背景,介绍命题公式主析(合)取范式的有关概念,写出生成命题公式主析(合)取范式的算法及代码。
(2)要求:
简述命题逻辑的基本概念及应用背景;
设计求命题公式主析取范式的算法;
写出算法的代码,在计算机上实现生成命题公式主析(合)取范式的功能;
任给一个命题公式,系统可自动生成该公式的主析取范式。
3.笛卡尔乘积
(1)给出两个或n个集合,输出它们的笛卡尔乘积。
(2)算法尽量作为软件来开发,即最后提交的是可视化的软件,软件实现的功能最少包括:
图形显示(应能让用户自主输入集合元素),图形显示笛卡尔乘积的结果
三、实验环境
使用visualC++6.0为编程软件,采用C语言为编程语言实现。
四、实验原理及过程
(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都存在与其等价的主合取范式,并且是惟一的。
(7)序偶定义
由两个元素x和y(x=y)按一定顺序排列成的二元组叫做一个有序对或序偶,记作,其中x是它的第一元素,y是它的第二元素。
有序对;具有以下性质:
1.当x≠y时,≠[1].
2.=;的充分必要条件是x=u且y=v.
(8)笛卡尔积定义
设A,B为集合,用A中元素为第一元素,B中元素为第二元素构成的有序对,所有这样的有序对组成的集合叫做A与B的笛卡尔积,记作AxB.
笛卡尔积的符号化为:
AxB={|x∈A∧y∈B}
(9)笛卡尔积的运算性质
对任意集合A,根据定义有
AxΦ=Φ,ΦxA=Φ
一般地说,笛卡尔积运算不满足交换律,即
AxB≠BxA(当A≠Φ∧B≠Φ∧A≠B时)
笛卡尔积运算不满足结合律,即
(AxB)xC≠Ax(BxC)(当A≠Φ∧B≠Φ∧C≠Φ时)
笛卡尔积运算对并和交运算满足分配律,即
Ax(B∪C)=(AxB)∪(AxC)
(B∪C)xA=(BxA)∪(CxA)
Ax(B∩C)=(AxB)∩(AxC)
(B∩C)xA=(BxA)∩(CxA)
五、实验数据及结果分析
1.命题公式真值表及主合/析取范式生成系统
进入界面
非运算
或运算
与运算
蕴含运算
等价运算
与或非蕴含等价综合运算
2.笛卡尔乘积生成系统
进入界面
输入3个集合
运行结果
结果分析:
第1题关于命题真值表及主析/合取范式由于本身关系比较密切,故我直接将两个做在了一起,这个程序从功能上来说,达到了题目要求的各个功能,可以运算与,或,非,蕴含,等值条件组成的表达式,并且支持括号运算,所以,总体上来说,虽然还有一些不完善的部分,但是整体是比较可以的。
第2题笛卡尔乘积生成系统比较简单,仅用指针和数组就可以完成,效果还不错。
六、程序清单
第1题,命题公式真值表及主析/合取范式系统源代码
#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;i2if(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;i1printf("%c",ccu[i1]);
printf("");
puts(sz);
printf("\n");
for(i1=0;i1icu[i1]=0;
for(i2=0;i2printf("%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;i2printf("%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;iif(ckh[i]==')')//找到第一个)
break;
for(j=wz[i-1]+1,h=0;jxs1[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;iif(sz[i]=='!
')
{for(i1=0;i1if(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;i1sz[i1]=sz[i1+1];//将后续式子前移一项
}
p1=-1;
j1=j;
for(i=0;iif(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;i1sz[i1]=sz[i1+2];
i=i-1;
}
for(i=0;iif(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;i1sz[i1]=sz[i1+2];
i--;
}
for(i=0;iif(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;i1sz[i1]=sz[i1+2];
i--;
}
for(i=0;iif(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;i1sz[i1]=sz[i1+2];
i--;
}
returndt[j+1];//返回结果
}
}
第2题,笛卡尔乘积生成系统
#include
structstudent/*定义一个结构体存储数据*/
{
intst;/*存储每个集合的元素的个数*/
chara[10][6];/*存放集合的元素*/
}b[5];/*定义一个结构体数组来表示集合*/
intn;/*标志集合的个数*/
voidmain()
{
voidprint();/*笛卡尔乘积函数的说明*/
inti,j;
for(j=0;j<5;j++)/*ST初始化*/
b[j].st=0;
n=0;
printf("***************************************\n");//标语
printf("**欢迎进入**\n");
printf("**笛卡尔乘积生成系统**\n")