离散数学实验报告Word文档下载推荐.docx
《离散数学实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告Word文档下载推荐.docx(28页珍藏版)》请在冰豆网上搜索。
实验BC的实现算法,开发者采用了指导老师所推荐的算法逻辑,其具体说明如下:
(1)将二进制加法模拟器赋初值0。
(2)计算模拟器中所对应的一组真值指派下合式公式的真值。
(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。
(4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转
(2)。
注意,在进行表达式求值的时候,可先将带括号的中缀表达式利用栈结构转换为不带括号的后缀表达式(逆波兰式),然后进行计算。
实验BC的程序编写思路大体上完全符合这样的设计思路,通过对数据结构中“堆栈”的概念来进行设计。
具体说来,程序中定义了两个重要的数组,一个用于表达式的计算,另外一个用于指派真值。
首先编写了一个将输入的字符串转化为可计算的表达式的函数,之后定义联结词的栈内和栈外的优先级,用于表达式的转化。
然后,编写了一个计算函数,用于模仿实数加法器进行表达式计算,并且用数组构建了一个二进制加法器,用于指派真值。
为了提高程序的容错能力,还编写了一个检查输入格式的函数。
最后,就是问题的解决函数了,首先将用户输入的表达式进行输入格式的检查,确认无误后,将字符串转化为可计算的表达式,保存在特定的堆栈中,之后,模仿实数加法器产生一个真值,同时对表达式进行计算,输出到真值表的显示界面上,并且根据真值来入栈,成真指派入析合栈,成假指派入合析栈,最后根据析合栈和合析栈的内容来进行析合范式与合析范式的输出。
第三章实验数据及结果分析
3.1主程序ABC.c的功能测试及结果分析
主程序是根据用户不同的选择来调用不同的函数,从而满足用户的使用需求,当然主程序界面友好,有清楚地操作说明,方便用户进行使用。
同时,它也有基本的容错能力,能够对没有按照要求的输入进行控制,在屏幕上显示提示语,要求用户重新输入。
这就是主程序控制的主界面。
3.1.1输入数字“1”
当输入数字“1”时,程序会显示实现实验A的功能界面。
3.1.2输入数字“2”
当输入数字“2”时,程序会显示实现实验BC的功能界面。
3.1.3输入数字“3”
当输入数字“3”时,程序会显示退出界面。
3.1.4输入其他字符时
当输入其他字符时时,程序会在屏幕上显示相应的提示语,要求用户重新输入。
3.2实验A的功能测试和结果分析
3.2.1测试数据为“p=T和q=F”
当测试数据为“p=T和q=F”时,程序会显示他们的合取、析取、条件和双条件的真值。
3.2.2测试数据为“p=F和q=F”
当测试数据为“p=F和q=F”时,程序会显示他们的合取、析取、条件和双条件的真值。
3.2.3测试数据为“p=A和q=F”
当测试数据为“p=A和q=F”时,程序检测出p是非法的输入格式,会在屏幕上显示相应的提示语,要求用户重新输入。
3.2.4测试数据为“p=T和q=A”
当测试数据为“p=T和q=A”时,程序检测出q是非法的输入格式,会在屏幕上显示相应的提示语,要求用户重新输入。
3.2.5测试数据为“p=F和q=F”,之后返回主界面
3.3实验BC的功能测试和结果分析
3.3.1测试数据为“a&
b|c#”
当测试数据为“a&
b|c#”时,程序会求出这个命题公式的真值表,并根据真值表求出主范式。
3.3.2测试数据为“(a>
b)|(c&
d)#”
当测试数据为“(a>
d)#”时,程序会求出这个命题公式的真值表,并根据真值表求出主范式。
3.3.3测试数据为“(a>
d)”
d)”时,程序检测出表达式的后面没有“#”,判断此次是非法的输入格式,会在屏幕上显示相应的提示语,要求用户重新输入。
3.3.4测试数据为“a&
b|c”
b|c”时,程序检测出表达式的后面没有“#”,判断此次是非法的输入格式,会在屏幕上显示相应的提示语,要求用户重新输入。
第四章实验收获和心得体会
4.1实验收获
通过这次实验,我学习了很多东西,也成长了许多,它使我意识到了很多原来没有意识到的东西。
首先,我重新认识到C和C++语言的重要性,深刻的认识到了这些语言通过有序的组织可以实现意想不到的效果。
其次,我知道了离散数学的那些抽象深奥的公式竟然也可以通过编程在计算机上实现,这种尝试让在课堂上学习的那些知识变得生动可爱,它们不再是黑板上、书本里面那一个个无聊死板的字眼,而是充满想象力、拥有无穷魅力的精灵。
再次,它提高了我的计算机编程能力,使我感觉到了编程的乐趣,提供给我无穷的继续学习编程语言的动力。
最后,这次实验令我感觉到了理论和实际的结合原来可以如此紧密的,他们之间的联系可以产生神奇的效果和无穷的力量。
4.2心得体会
这次真的使我意识到了很多原来没有意识到的问题,有时候一些很小的问题,也会令人很是头痛。
在刚开始编写程序的时候,为了实现最基本的输入和输出功能,我却花了大量的时间在那上面。
原因在后来查阅的很多资料后才知道的,像scanf函数之类的小函数,其实是还有很多需要注意的地方的。
之后,在编写头文件程序的时候,遇到很多诸如跳转控制、数组操作、堆栈运用等等具体的问题。
经过不断的尝试摸索,通过查阅大量资料,后来才慢慢的攻克一个个的难点。
在C语言和C++语言的运用时,经常会有混淆的地方,通过一次次的提醒和注意,到后来终于可以慢慢的将它们区分开了。
最重要的体会就是,通过自己不断的努力,很好的完成一个任务,这种能够成就感,才是作为一个大学生最大的快乐。
第五章实验源程序清单
5.1主程序ABC.c的代码
#include"
stdio.h"
string.h"
#include"
stdlib.h"
A.h"
BC.h"
charflag1,flag3,flag4;
voidini()
{
printf("
*******************************************************************************\n"
);
\n"
请选择您要进行的操作项目:
1、输入两个命题变元的真值,求它们的合取、析取、条件和双条件的真值\n"
2、求任意一个命题公式的真值表,并根据真值表求主范式\n"
3、退出系统\n"
********************************************************************************\n"
}
voidend()
谢谢使用本系统,欢迎下次使用!
\n"
voidmain()
while(!
flag3)
{
while(!
flag1)
{
if(flag4==0)
system("
cls"
ini();
scanf("
%d"
&
i);
fflush(stdin);
if(i==1||i==2||i==3)
{
flag3=1;
flag4=0;
if(i==1)
PQ();
elseif(i==2)
{
symbola;
a.solve();
}
else
flag1=1;
}
else
printf("
输入格式有误,请重新输入!
flag4=1;
}
}
end();
5.2头文件A.h的代码
chari,p,q,t,mea,flag,flag2;
intp1,q1;
voidana()
flag2)
printf("
请输入p的真值(T或F)\n"
scanf("
%c"
p);
fflush(stdin);
if(p=='
T'
||p=='
F'
)
printf("
请输入q的真值(T或F)\n"
q);
if(q=='
||q=='
if(p=='
p1=0;
else
p1=1;
if(q=='
q1=0;
q1=1;
if(p1|q1)
t='
;
p析取q为%c\n"
t);
if(p1&
q1)
p合取q为%c\n"
if((!
p1)|q1)
p条件q为%c\n"
if(p1==q1)
p双条件q为%c\n"
flag2=1;
else
else
voidPQ()
flag)
ana();
flag2=0;
******************************是否要继续输入?
(Y或N)****************************\n"
mea);
if(mea=='
N'
flag=1;
flag=0;
5.3头文件BC.h的代码
stdafx.h"
iostream"
cstring"
stack"
cmath"
#definemaxsize100
usingnamespacestd;
charstr[100];
//输入的表达式
intzhipai[20]={0};
//用于指派真值的数组
intlength;
//逻辑表达式长度
charexpression[100];
//用于计算的数组
classsymbol{
public:
voidsolve();
voidClear(){}
private:
voidchange();
intCalculate();
voidcheck();
boolGet2Operands(double&
left,double&
right);
voidDoOperator(charop);
stack<
int>
s;
//运算栈
};
boolsymbol:
:
Get2Operands(double&
right){//取两运算值
if(s.size()==0){
cerr<
<
"
MissOperand!
endl;
returnfalse;
right=s.top();
s.pop();
left=s.top();
returntrue;
voidsymbol:
DoOperator(charop){//单次运算
doubleleft,right;
boolresult=Get2Operands(left,right);
if(result)
switch(op){
case'
|'
s.push(left||right);
break;
//或运算
&
'
s.push(left&
//与运算
>
s.push(!
left||right);
//蕴涵运算
!
s.push((!
right)&
left);
//非运算
='
s.push(left==right);
//等价运算
else
Clear();
change()//将输入的字符串转化为可计算的表达式
intk=0;
intflag=1;
intcount=0;
//命题变元个数
for(inti=0;
i<
pow(2,count);
i++)
k=1;
for(intm=0;
m<
length;
m++)
if(isalpha(str[m]))//将原来的命题变元修改为真值
if(flag==1)
if(zhipai[k]==0)
expression[m]='
0'
1'
k++;
flag=1;
for(intt=m;
t>
=0;
t--)
if((str[m+1]==str[t])&
isalpha(str[m+1])&
isalpha(str[t]))
flag=0;
expression[m]=str[m];
//逻辑联结词不变
for(intt=0;
t<
t++)
for(intj=t;
j<
j++)
if(str[t]==str[j])
{
expression[j]=expression[t];
//相同的命题变元复制赋值
}
voidplus(inta[],intq)//二进制加法器,用于指派真值
a[q]=a[q]+1;
for(inti=q;
a[i]==2;
i--)
{
a[i]=0;
a[i-1]=a[i-1]+1;
intisp(charch)//联结词的栈内优先级
switch(ch){
case'
#'
return0;
('
return1;
return10;
return9;
return7;
return5;
return3;
)'
return12;
default:
return-1;
inticp(charch)//联结词的栈外优先级
return11;
return8;
return6;
return4;
return2;
intsymbol:
Calculate()//模仿实数加法器进行表达式计算
char>
h;
charch,y;
h.push('
for(inttemp=0;
temp<
length-1;
temp++){
ch=expression[temp];
if(isdigit(ch))//命题变元真值入栈
if(ch=='
s.push(0);
s.push
(1);
elseif(ch=='
)//运算括号内的
for(y=h.top(),h.pop();
y!
y=h.top(),h.pop()){
DoOperator(y);
else{
)//非运算,在!
前加1,将!
视作双目操作符
isp(y)>
icp(ch);
y=h.top(),h.pop())
h.push(y);
h.push(ch);
while(h.size()!
=1){
y=h.top();
h.pop();
DoOperator(y);
cout<
s.top()<
//输出最终结果
returns.top();
voidsymbol:
check();
//检查函数的预先声明
solve()//问题的解决
cout<
********************************************************************************"
请输入命题逻辑表达式:
(注意:
命题变元在a~z中选取,变元个数不要超过20个,或运算用|,与运算用&
,非运算用!
,蕴涵运算用>
,等价运算用=,以#结尾)"
i