离散数学实验报告.docx
- 文档编号:654316
- 上传时间:2022-10-11
- 格式:DOCX
- 页数:18
- 大小:175.14KB
离散数学实验报告.docx
《离散数学实验报告.docx》由会员分享,可在线阅读,更多相关《离散数学实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
离散数学实验报告
实验报告
(2016/2017学年第一学期)
课程名称
离散数学
实验名称
利用真值表法求取主析取范式以及主合取范式的实现
实验报告
实验名称
利用真值表法求取主析取范式以及主合取范式的实现
指导教师
实验类型
验证
实验学时
4
实验时间
一、实验目的与要求
内容:
编程实现用真值表法求取任意数量变量的合式公式的主析取范式与主合取范式。
要求:
能够列出任意合式公式的真值表并给出相应主析取与主合取范式。
二、实验环境(实验设备)
X86架构计算机
操作系统:
Windows732bit
IDE:
CodeBlokcs16、02
编程语言:
C++
编译器:
GCC
三、实验原理及内容
内容:
编程实现用真值表法求取任意数量变量的合式公式的主析取范式与主合取范式。
原理:
先将中缀表达式转换成后缀表达式,再将后缀表达式中每一个字母变量一一赋值,用递归枚举的方法枚举所有赋值情况,并且用map映射将每一个字母变量与当前被枚举的值一一映射,对每一种赋值情况调用后缀表达式计算函数计算后缀表达式的值,打印真假情况。
如果就是真,记录到名为zhen的vector不定长数组中,如果就是假,记录到名为jia的vector不定长数组中。
最后根据zhen与jia的不定长数组来打印主析取范式与主合取范式。
此程序可以实现任意数量的字母变量的主析取范式求取与主合取范式求取,以及真值表打印。
实验报告
第一步:
预处理
预处理,去除中缀表达式中条件->中的>,与双条件<=>中的=与>,这样,所有的运算符只就是一个字符,后期处理起来更加方便。
voidddd()
{
string:
:
iteratori=zhong、begin();//string类迭代器,需在头文件加入#include
intflag=1;
while(flag)
{
flag=0;
for(i=zhong、begin();i!
=zhong、end();++i)
{
if(*i=='>')
{
zhong、erase(i);
flag=1;
break;
}
if(*i=='=')
{
zhong、erase(i);
flag=1;
break;
}
}
}
}
第二步:
将中缀表达式转换后缀表达式
利用栈与优先级函数来将中缀表达式转换成后缀表达式,此函数另一个功能就是将中缀表达式中所有出现过的字母变量都保存包名为alpha的string类中(string类为STL中的string,需要在头文件加入#include
全局变量:
stringzhong;//中缀表达式
charhou[1000];//后缀表达式
stringalpha;//存放所有字母变量
优先级函数:
inticp(chara)//栈外优先级
{
if(a=='#')return0;
if(a=='(')return12;
if(a=='!
')return10;
if(a=='&')return8;
if(a=='|')return6;
if(a=='-')return4;
if(a=='<')return2;
if(a==')')return1;
}
intisp(chara)//栈内优先级
{
if(a=='#')return0;
if(a=='(')return1;
if(a=='!
')return11;
if(a=='&')return9;
if(a=='|')return7;
if(a=='-')return5;
if(a=='<')return3;
if(a==')')return12;
}
voidchange()//中缀表达式转换后缀表达式
{
intj=0;
stack
charch,y;
s、push('#');
chart1,t2;
stringstreamss(zhong);//字符串流,需要在头文件加入#include
while(ss>>ch,ch!
='#')
{
if(isalpha(ch))//判断就是不就是字母,如果就是,加入到alpha字符串中
{
hou[j++]=ch;//并且加入到后缀表达式字符串中
if(alpha、find(ch)==-1)
{
alpha、push_back(ch);
}
}
elseif(ch==')')
{
for(y=s、top(),s、pop();y!
='(';y=s、top(),s、pop())
{
hou[j++]=y;
}
}
else
{
for(y=s、top(),s、pop();icp(ch)<=isp(y);y=s、top(),s、pop())
{
hou[j++]=y;
}
s、push(y);
s、push(ch);
}
}
while(!
s、empty())
{
y=s、top();
s、pop();
if(y!
='#')
{
hou[j++]=y;
}
}
hou[j]='#';
}
第三步:
递归枚举每一个字母变量的取值情况
用深度优先搜索(dfs)的思想进行递归枚举,如果当前递归深度已经达到字符串长度,就说明所有字母已经取值成功,字母的“值”用map进行映射(需要在头文件加入#include
计算完成后,打印真值,如果当前计算结果就是true,那么加入到zhen数组中,以待后面的主析取范式打印调用,如果就是false,加入到jia数组,以待后面的主合取范式打印调用。
全局变量:
map
structnote
{
inta[100];
};
vector
vector
voiddfs(intcur)//递归枚举每一种字符变量的取值情况
{
if(cur==alpha、size())
{
intans=cal();
for(inti=0;i { if(M[alpha[i]]) { printf("T\t"); } else { printf("F\t"); } } if(ans==1)//真值为T计入到zhen数组,以待后面主析取范式使用 { printf("T\n"); notet; for(inti=0;i { t、a[i]=M[alpha[i]]; } zhen、push_back(t); } else//真值为F计入到jia数组,以待后面主合取范式使用 { printf("F\n"); notet; for(inti=0;i { t、a[i]=M[alpha[i]]; } jia、push_back(t); } return; } M[alpha[cur]]=1;//深度优先搜索(dfs)进行递归枚举 dfs(cur+1); M[alpha[cur]]=0; dfs(cur+1); } intcal()//对赋值后的后缀表达式进行计算,返回计算结果 { stack charch; intj=0; intt1,t2; while (1) { ch=hou[j]; if(ch=='#')break; if(ch==0)break; j++; if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) { s、push(M[ch]); } else { if(ch=='! ') { t1=s、top(); s、pop(); s、push(! t1); } elseif(ch=='&') { t1=s、top(); s、pop(); t2=s、top(); s、pop(); if(t1==1&&t2==1) { s、push (1); } else { s、push(0); } } elseif(ch=='|') { t1=s、top(); s、pop(); t2=s、top(); s、pop(); if(t1==0&&t2==0) { s、push(0); } else { s、push (1); } } elseif(ch=='-') { t1=s、top(); s、pop(); t2=s、top(); s、pop(); if(t1==0&&t2==1) { s、push(0); } else { s、push (1); } } elseif(ch=='<') { t1=s、top(); s、pop(); t2=s、top(); s、pop(); if((t1==1&&t2==1)||(t1==0&&t2==0)) { s、push (1); } else { s、push(0); } } } } intans=s、top(); returnans; } 最后一步: 打印主析取范式与主合取范式 最后一步,也就是最简单的一步,打印主析取范式与主合取范式,由于前面在递归枚举dfs的过程中已经把真值表顺带打印了,所以就只剩下主析取范式与主合取范式了,在dfs过程中,所有取值为真的情况已经加入zhen的vec
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 离散数学 实验 报告