离散数学命题公式真值表C++或C语言实验报告
离散数学实验——求真值表.docx
一实验目的 (1)二实验内容 (1)三实验环境 (1)四实验原理和实现过程(算法描述) (1)五实验数据及结果分析; (3)六源程序清单; (5)七其他收获和体会。
(14)一实验目的熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
二实验内容1.从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
(A)2.求任意一个命题公式的真值表(B,并根据真值表求主范式(C))三实验环境C或C++语言编程环境实现。
四实验原理和实现过程(算法描述)A:首先提示用户输入真值指派,然后判断用户输入的是否是0或者1,如果不是则利用while语句提示错误,然后提示重新输入直至输入正确,再根据用户输入的真值给代表合取,析取,蕴含,双条件的变量赋值,再以两行表格形式输出所得结果。
最后提示按#键退出, 否则继续循环求真值。
B:主要思路:首先提示用户输入表达式,然后编写并调用一个函数将表达式转换为逆波兰式,在转换的同时,插入部分语句将表达式中的变量名存储到数组bianl[N]中,然后输出存好的各变量名及用户输入的表达式(建立表头),将每次的真值指派存在数组zhi[]中,编写函数zzhi ()每次调用zzhi ()时都使数组zhi □中的真值加1, (利用递推实现加一时可能的进位,)然后编写并调用一函数qiuzhi ()计算每次真值指派下的逆波兰表达式的值,再输出各真值指派和求出的表达式的真值,然后调用函数zzhiO将真值指派的数组加1, 最后外围利用while 语句循环输出每个不同的真值指派和该指派下表达式的值。
将表达式转换成逆波兰式并将变量提取的算法:首先需要分配2 个栈,一个作为临时存储运算符的栈fu[], —个作为输入逆波兰式的栈nibol:],从中缀式的左端开始取字符,逐序进行如下步骤:(1)若取出的字符是字母,则该字母直接送入nibol[]栈。
同时为了找出所有变量,将该变量名与数组bianl[]中已有的元素比较, 如果bianl □中还没有该字母,则该字母是新出现的变量,将其录入数组bianl []中。
离散数学实验报告真值
离散数学实验报告真值四川⼤学计算机学院实验报告实验名称:求合适公式的真值指导教师:姓名:学号:班级:⽇期:⼀.实验⽬的设计⼀个程序,来达到输⼊⼀个正确的合式公式,求它的真值表。
通过实验,更好地掌握离散数学中的概念、性质和运算。
⼆.功能设计任意输⼊的合适公式计算其真值表并输出三.界⾯设计四.实现步骤算法逻辑如下:(1)任意设计⼀个真值判断表达式,并使其赋值计算(2)计算模拟器中所对应的⼀组真值指派下合式公式的真值(3)输出真值表中对应于模拟器所给出的⼀组真值指派及这组真值指派所对应的⼀⾏真值。
五.运⾏结果六.源代码#include#include#includeusing namespace std;string calcValue(string value1);string calcValueNop(string value1);string caclAnd(string x,string y);string caclOr(string x,string y);string caclNot(string x);int main(){string in,varList="";//="!a+b^c"cout<<"*****************************************\n"<cout<<"** 欢迎进⼊逻辑运算软件**\n"<cout<<"** (可运算真值表,⽀持括号) **\n"<cout<<"** ⽤!表⽰否定**\n"<cout<<"** ⽤^表⽰合取**\n"<cout<<"** ⽤+表⽰析取**\n"<cout<<"*****************************************\n\n"<cout<<"请输⼊命题公式:注意: !,^,+,(,),字母为合法,不要有数字、空格,括号也要匹配!"< cout<<"⽰例:!a+b^c"<cin>>in;cout<<"输⼊命题公式"<int length=in.length();int i=0,j=0;for(i=0;ichar code=in[i];if( ((code>=97)&&(code<123)||((code>=65))&&(code<81))&&varList.find(code, 0)==-1 ) varList+=code;}int n=varList.length();for(i=0;icout<int flag;char *trow=new char[n];for(i=0;ifor(i=0;ifor(j=0;jcout<string value1=in;for(j=0;jchar x=varList[j];for(int k=0;kif(value1[k]==x)value1[k]=trow[j];}cout<flag=1;for(j=n-1;j>-1;j--) {int temp;temp=int(trow[j])-48;flag=flag+temp;if(flag==2) {trow[j]='0';flag=1;}else{trow[j]='1';flag=0;break;}}}delete trow;system("pause");return 0;}string calcValue(string value1){int nlp=value1.find('(',0);int nrp=value1.length();string x="",v="";int i=nlp+1;while(nlp>=0) {x=value1.substr(i,1);if(x=="("){nlp=i;i++;}else{if(x==")"){nrp=i;v=calcValueNop(value1.substr(nlp+1,nrp-nlp-1));value1=(nlp>0?value1.substr(0,nlp):"")+v+((nrp+1)<=value1.length()?value1.substr(n rp+1):"");nlp=value1.find('(',0);i=nlp+1;}else{i=i+1;}}if(i>=value1.length()){nlp=value1.find('(',0);i=nlp+1;}}return calcValueNop(value1);}string calcValueNop(string value1){int nnot=value1.find('!',0);while(nnot>=0) {value1=(nnot>0?value1.substr(0,nnot):"")+caclNot(value1.substr(nnot+1,1))+((nnot+ 2)<=value1.length()?value1.substr(nnot+2):"");nnot=value1.find('!',0);}int nand=value1.find('^',0);while (nand>0){value1=((nand-1)>0?value1.substr(0,nand-1):"")+caclAnd(value1.substr(nand-1,1),va lue1.substr(nand+1,1))+((nand+2) <=value1.length()?value1.substr(nand+2):"");nand=value1.find('^',0);}int nOr=value1.find('+',0);while (nOr>0){value1=((nOr-1)>0?value1.substr(0,nOr-1):"")+caclOr(value1.substr(nOr-1,1),value1. substr(nOr+1,1))+((nOr+2)<=value1.length()?value1.substr(nOr+2):"");nOr=value1.find('+',0);}return value1;}string caclAnd(string x,string y){if ((x=="1") && (y=="1")){return "1";}else {return "0";}}string caclOr(string x,string y){if ((x=="0") && (y=="0")){return "0";}else {return "1";}}string caclNot(string x){if (x=="1") {return "0";}else {return "1";}}七.⼼得体会离散数学课程在各学科领域,特别在计算机科学与技术领域有着⼴泛的应⽤,同时离散数学也是计算机专业的许多专业课程,如程序设计语⾔编译技术、⼈⼯智能、算法设计与分析等必不可少的先⾏课程。
离散数学上机实验报告
一、实验内容
从键盘输入二元关系用沃尔算法求出它的传递闭包,并输出。
二、实验步骤
熟悉沃尔算法,然后将其用程序编写出来,任意输入二元关系,观察程序运行结果,
用另一种算法算出结果,与其比较,调试程序。
三、实验代码
#include<stdio.h>
int main()
{
int n,i,j,k,a[10][10];
printf("﹁q=0\n");
printf("p∧q=1\n");
printf("p∨q=1\n");
printf("p→q=1\n");
printf("p<->q=1\n");
}
continue;
}
if('n'==t)
break;
}
return 0;
}
四、实验体会
求真值运算中,应注意各种连接词的试用方法,以及其在不同情况下的真值。
printf("\n");
}
return 0;
}
四、实验体会
熟悉并使用沃尔算法,关系矩阵中只有0和1,所以用沃尔算法求得的数若大于1,应该返回1,其余不变。
实验四、三种闭包运算
一、实验内容
从键盘输入一个二元关系,求它的自反闭包,对称闭包,传递闭包,并输出。
二、实验步骤
编写程序,从键盘输入一个二元关系,当求传递闭包时,试与沃尔算法的传递闭包做比较,观察程序运行结果,调试程序。
char t;
while(t)
{
printf("是否运算程序(y/n):\n");
任意命题公式的真值表
实验报告实验名称:任意命题公式的真值表实验目的与要求:通过实验,帮助学生更好地掌握计算机科学技术常用的离散数学中的概念、性质和运算,包括联结词、真值表、运算的优先级等,提高学生编写实验报告、总结实验结果的能力,培养学生的逻辑思维能力和算法设计的思想,能够独立完成简单的算法设计和分析,进一步用它们来解决实际问题,帮助学生学习掌握C/C++语言程序设计的基本方法和各种调试手段,使学生具备程序设计的能力。
实验内容提要:求任意一个命题公式的真值表实验步骤:(一)、关于命题公式的形式和运算符(即联结词)的运算首先根据离散数学的相关知识,命题公式由命题变元和运算符(即联结词)组成,命题变元用大写字母英文表示(本次试验没有定义命题常元T和F,即T、F都表示命题变元),每个命题变元都有两种真值指派0和1,对应于一种真值指派,命题公式有一个真值,由所有可能的指派和命题公式相应的真值按照一定的规范构成的表格称为真值表。
目前离散数学里用到的包括扩充联结词总共有九种,即析取(或)、合取(与)、非、蕴含、等值、与非、或非、异或、蕴含否定,常用的为前五种,其中除了非运算为一元运算以外,其它四种为二元运算。
所以本次实验设计时只定义了前五种运算符,同时用“/”表示非,用“*”表示合取,用“+”表示析取,用“>”表示蕴含,用“:”表示等值,且这五种运算符的优先级依次降低,如果需用括号改变运算优先级,则用小括号()改变。
以下为上述五种运算符运算时的一般真值表,用P和Q表示命题变元:1.非,用“/”表示2.合取(与),用“*”表示3.析取(或),用“+”表示4.蕴含,用“>”表示5.等值,用“:”表示(二)、命题公式真值的计算对于人来说,计算数学表达式时习惯于中缀表达式,例如a*b+c,a*(b+c)等等,而对于计算机来说,计算a*b+c还好,计算a*(b+c)则困难,因为括号的作用改变了运算的顺序,让计算机识别括号而改变计算顺序显得麻烦。
最新离散数学命题公式真值表C或C语言试验报告
精品文档离散数学实验报告姓名:鲍佳珍专业班级:12级计算机本部一班实验成绩:201212201401016 学号:【实验题目】1.命题逻辑实验二【实验目的】2.熟悉掌握命题逻辑中真值表,进一步能用它们来解决实际问题。
【实验内容】3.求任意一个命题公式的真值表【实验要求】4、C++语言编程实现C或【算法描述】5.1.实验原理表征逻辑事件输入和输出之间全部可能状态的表格。
列出命题公式真值表:命题公式的取值由组成命题公式的命表示假。
1通常以表示真,0 真假值的表。
真题变元的取值和命题联结词决定,命题联结词的真值表给出了真假值的算法。
值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。
实验过程2.输出结果:然后用函数运算,首先是输入一个合理的式子,生成相应真值表,要求可生成逻辑非、合取、析取、蕴含、双条件表达式的真值表,例如: !a输入输出真值表如下:a !a1 001a&&b输入输出真值表如下:a b a&&b0 0 00 1 01 0 01 1 1a||b输入输出真值表如下:精品文档.精品文档a b a||b0 0 00 1 11 0 11 1 1输入a->b输出真值表如下:a b a->b0 0 10 1 11 0 01 1 1输入a<>b (其中<>表示双条件)输出真值表如下:a b a<>b0 0 10 1 01 0 01 1 16.【源程序(带注释)】#include<stdio.h>#include<string.h>void hequ();void yunhan();void xiqu();void shuang();void fei();//声明五个函数int main(){int ch;char s[10];精品文档.精品文档牰湩晴尨欢迎使用命题公式真值表查找软件\n\n);printf(.合取 2.析取 3.蕴含 4.双条件 5.非0.结束查找\n);//软件使用界面的输出scanf(%d,&ch);while(ch){printf(\\n您能查找真值表的命题公式有以下几种:\n\n);printf(.合取请输入a&&b 2.析取请输入a||b 3.蕴含请输入a->b 4.双条件请输入a<>b 5.非请输入!a\n);//选择输入的公式类型getchar();牰湩晴尨请输入您所需要查询的公式:);scanf(%s,s);if(!strcmp(s,a&&b))hequ();else if(!strcmp(s,!a))fei();else if(!strcmp(s,a||b))xiqu();else if(!strcmp(s,a->b))yunhan();精品文档.精品文档else if(!strcmp(s,a<>b))//将输入的公式与程序内存在的公式进行比较shuang();else牰湩晴尨对不起,您所要查找的公式不存在!\n\n);printf(\1.继续查找0. 结束\n\n);scanf(%d,&ch); //使程序循环}return 0;}void hequ(){a&&b\n); printf(a b0\n); printf( 10\n); printf( 00\n); 0 printf(1\n); printf( 1}void xiqu()a||b\n); b printf(a 1\n); 1 printf(精品文档.精品文档printf( 0 0\n); printf( 0 1\n); printf( 1 1\n); }void yunhan(){printf(a b a->b\n); 1\n); printf( 11\n); 0 printf( printf( 0\n); 01\n);printf( 1}void fei(){!a\n); printf(a0\n); printf(1\n); printf(void shuang(){printf(a b a<>b\n);0\n); printf( 1精品文档.精品文档printf( 0 1\n);printf( 0 0\n);printf( 1 1\n);} //定义五个函数7.【实验结果与分析总结(含运行结果截图)】输入界面输入公式并输出真值表精品文档.精品文档继续查找结束程序精品文档.精品文档精品文档.。
离散数学实验报告命题逻辑—构造命题公式的真值表
【实验目的】使学生熟练掌握利用计算机语言实现逻辑运算的基本方法。
【实验内容】对给出的任意一个命题公式(不超过四个命题变元),使学生会用C语言的程序编程表示出来,并且能够计算它在各组真值指派下所应有的真值,画出其真值表。
【实验原理】给出任意一个命题公式,我们可以将它用C程序表示出来,并且能够计算它在各组真值指派下所应有的真值(或是逻辑运算的结果)。
这有多种方法。
上面我们已经给出了逻辑连结词的定义,根据这种定义方法,我们也可以把一个命题公式表示成为条件语句中的条件表达式,这样我们就可以得到该命题公式的逻辑运算结果了。
【程序代码】#include <bits/stdc++.h>using namespace std;int a[8][3]={{0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{1,1,0},{1,1,1}};int b[8]={0,0,0,0,0,0,0,0};int xa[8]={0,0,0,0,0,0,0,0};int s(char c,int as,int i){//1 true;0 falseif(c=='|'){if(a[i][as]==1||a[i][as+1]==1){return 1;} else{return 0;}}if(c=='&'){if(a[i][as]==1&&a[i][as+1]==1){return 1;} else{return 0;}}if(c=='='){if(a[i][as]==a[i][as+1]){return 1;} else{return 0;}}if(c=='!'){if(a[i][as]==a[i][as+1]){return 0;return 1;}}if(c=='>'){if(a[i][as]==1||a[i][as+1]==0){return 0;} else{return 1;}}}int so(char c,int i,int as){if(c=='|'){if(xa[i]==1||a[i][as+1]==1){return 1;} else{return 0;}}if(c=='&'){if(xa[i]==1&&a[i][as+1]==1){return 1;} else{return 0;}}if(c=='='){if(xa[i]==a[i][as+1]){return 1;} else{return 0;}}if(c=='!'){if(xa[i]==a[i][as+1]){return 0;} else{return 1;}}if(c=='>'){if(xa[i]==1||a[i][as+1]==0){return 0;return 1;}}}int main(void) {string f;cin>>f;char c1=f[1];char c2=f[3];for(int i=0;i<8;i++){for(int j=0;j<3;j++){printf("%d ",a[i][j]);}printf("\n");}for(int i=0;i<8;i++){xa[i]=s(c1,0,i);}for(int i=0;i<8;i++){b[i]=so(c2,i,1);}for(int i=0;i<8;i++){printf("%d\n",b[i]);}return 0;}【实验结果】【实验心得】。
离散数学实验
离散数学实验报告(实验一)专业:自动化班级:学号:姓名:日期2010.10.28一实验内容(二选一)1. 从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值(A)2. 求任意一个命题公式的真值表(B),并根据真值表求主范式(C)。
二实验目的熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
三实验环境进入Visual C++ 环境后,选择菜单“File | New”,在弹出的对话框中单击上方的选项卡“Projects”,选择“Win32 Console Application”工程类型,在“Project name”一栏中填写工程名例如MyFirst,在“Location”一栏中填写工程路径(目录). 选择菜单“Project | Add to Project | New”,为工程添加新的C++源文件。
选择菜单为工程添加新源文件在“File Name”栏填入新添加的源文件名,如MyFirst.cpp,“Location”一栏指定文件路径,按按钮“OK”完成C++源程序的系统新建操作。
编译源程序:选择Build | Build菜单(F7为快捷键),系统将会在Output窗口给出所有的错误信息和警告信息。
当所有错误修正之后,系统将会生成扩展名为.exe的可执行文件。
对于Output窗口给出的错误信息,双击可以使输入焦点跳转到引起错误的源代码处以进行修改。
执行程序:选择Build | Execute菜单项(Ctrl + F5为快捷键),执行程序,将会出现一个DOS窗口,按照程序输入要求正确输入数据后,程序即正确执行。
四实验原理和实现过程(算法描述)1.程序主界面本程序界面主要有两个操作,1:求真值。
2:求任何公式的真值。
操作1完成A 类题要求,操作2完成A,B类题要求。
如果出输入的操作项不是0,1,2,则会提示出错,再次选择。
其界面如图所示:2.算法描述和实现过程在做A类题时,算法实现,首先判断输入格式是否正确,在把蕴含(→),等值(←→),通过变换,化成只有非,合取和析取的等价公式,在利用C语言中的运算符非(!),与(&&)和或(||)算出任何两元变量的真值。
离散数学实验
离散数学实验实验一真值计算一、实验目的熟悉联结词合取、析取、条件和双条件的概念,编程求其真值。
二、实验内容(1)求任意一个命题公式的真值表:从键盘输入两个命题P 和Q 的真值,求它们的合取、析取、蕴含和等价的真值(2)利用真值表求任意一个命题公式的主范式(3)利用真值表进行逻辑推理三、实验报告要求列出实验目的、实验内容、实验步骤、源程序和实验结果。
#include#includeint main(){int p,q,hequ,xiqu,yunhan,dengjia;printf("请输入命题P和Q的真值(0或1)");scanf("%d%d",&p,&q);if(p!=0&&p!=1||q!=0&&q!=1)printf("输入错误");else{if(p==0&&q==0){hequ=0;xiqu=0;yunhan=1;dengjia=1;}else if(p==0&&q==1){hequ=0;xiqu=1;yunhan=1;dengjia=0;}else if(p==1&&q==0){hequ=0;xiqu=1;yunhan=0;dengjia=0;}else if(p==1&&q==1){hequ=1;xiqu=1;yunhan=1;dengjia=1;}printf("合取的真值为:%d\n",hequ);printf("析取的真值为:%d\n",xiqu);printf("蕴含的真值为:%d\n",yunhan);printf("等价的真值为:%d\n",dengjia);system("pause");return 0;}}实验二两个集合运算(交、并、补)一、实验目的集合论是一切数学的基础,也是计算机科学不可或缺的,在数据结构,数据库理论,开关理论,自动机理论和可计算理论等领域都有广泛的应用。
离散实验报告一
离散数学实验报告(一)一、实验目的求命题公式的真值表及其主析取范式和主合取范式二、问题分析本程序最终的目的应是求命题公式的主析取范式和主合取范式,而在有命题真值表的情况下,主析取范式和主合取范式的求解将变得十分简单。
所以,该程序的关键问题应该是求解命题公式的真值表,此后在真值表的基础上完成主析取范式和主合取范式的求解。
(一)前期分析与部分变量准备规定前提,真值表中的T/F在该程序中用布尔类型的1/0来表达。
如此,可以方便程序的编写与运算。
首先,我们要确定各个联结词的符号表达,为了方便讨论,不妨在此先令各联结词表达如下:合取(*)、析取(/)、否定(-)、单条件(%)、双条件(@)。
接着,我们就需要明确各联结词所对应符号在程序中的功能。
具体来看,合取与析取可以分别使用c++自带的&&(且)和||(或)进行布尔运算,取否定也可以直接使用!(取非)运算;而对于单条件、双条件这两个联结词来看,在c++中并无已有的运算定义,所以我们要利用函数定义的方式重新明确其含义。
而后,定义char类型数组a[]用于存储命题公式,为了方便程序的实现,我们将命题变元与联结词分开存储于char类型数组b[]和c[]中。
(二)真值表输出算法以下,我们便进入了程序的核心部分——完成真值表的计算与输出。
碍于本人c++编程知识的局限,暂时只能实现输入三个变元、无否定情况下的命题公式的真值表输出。
为了完成真值表的输出,要解决以下几个问题1. 真值表的格式与指派控制对此,我们使用三层for语句嵌套完成真值表的每一行输出。
在循环的同时,我们还需要提前定义一个布尔数组p[],以根据每一行的输出完成三个变元的指派,并将其存储于数组p[]中。
2.真值表每一行结尾的结果计算首先,我们需要定义一个布尔类型的过程存储数组x[],利用switch语句的嵌套分别判断两个联结词,使用相应的运算符(&&、||、!)和已定义的两个布尔类型函数(imp、equ),一次计算,并且将每一次的计算结果存储至x[]中,运算直至最后一步完成结果的输出。
离散数学-逻辑学-命题公式求真值表
离散逻辑学实验班级:10电信实验班学号:Q10600132 姓名:王彬彬一、实验目的熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
二、实验内容1. 从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
(A)2. 求任意一个命题公式的真值表(B,并根据真值表求主范式(C))三、实验环境C或C++语言编程环境实现。
四、实验原理和实现过程(算法描述)1.实验原理(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 表示假。
离散数学之逻辑运算和命题公式真值表
}
int shuangtiaojian(int P,int Q)
{
return(!P^Q);
}
int Pfaoding(int P)
{
return(!P);}来自int show(){
cout<<"P Q R P∧Q P∧R┐P∧R (P∧Q)∨(┐P∧R)"<<endl;
for(int p=0;p<2;p++)
(1)将二进制加法模拟器赋初值0
(2)计算模拟器中所对应的一组真值指派下合式公式的真值。
(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。
(4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转(2)。
#include <iostream.h>
int main()
1、逻辑联接词的运算
从键盘输入两个命题变元P和Q的真值,输出它们的合取、析取、条件、双条件和P的否定的真值。
#include <iostream.h>
int main()
{
int a,b;
int hequ(int P,int Q);
int xiqu(int P,int Q);
int tiaojian(int P,int Q);
}
int Pfaoding(int P)
{
if(P==0)
P=P;
else
P=1;
return(!P);
}
int show(int a,int b)
{
cout<<"P Q P∧Q P∨Q P→Q P←→Q┐P"<<endl;
离散数学实验报告
实验一一实验内容(选作AB类)1. 从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
(A)2. 求任意一个命题公式的真值表(B,并根据真值表求主范式(C))二实验目的熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
三实验环境C语言编程环境实现。
四 1、实现A类算法原理根据析取、合取的定义可用简单的算术运算求出结果,并将结果转换成逻辑值。
同样根据等价关系可将条件式及双条件式转换成析取和合取的运算。
此题较简单2、实现BC类算法原理算法逻辑如下:(1)将二进制加法模拟器赋初值0(2)计算模拟器中所对应的一组真值指派下合式公式的真值。
(3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。
(4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转(2)。
(5)在进行表达式求值的时候,可先将带括号的中缀表达式利用栈结构转换为不带括号的后缀表达式(逆波兰式),然后进行计算。
具体方法请参考数据结构中有关“栈”的知识。
五实验数据及结果分析1(A类)2(B类)从实验结果可以看到:当输入的数据不是逻辑值时须重新输入,当输入符合逻辑值才能继续下去。
从结果来看完全正确,由于界面有限没有把所有结果都贴上,根据运行情况来看没有错误六源程序清单1(A类)#include<stdio.h>//#include<string.h>main(){while(1) //输入符合逻辑值的命题变元P值{int a,b,c,d,e,f,g;while(1){printf("\ninput the logic value of the minti P(0 or 1):");scanf("%d",&a);if((a!=0)&&(a!=1)){printf("you have input the wrong value,please reinput");}else break;}while(1) //输入符合逻辑值的命题变元Q值{printf("\ninput the logic value of the minti Q(0 or 1):");scanf("%d",&b);if(b!=0&&b!=1)printf("you have input the wrong value,please reinput");else break;}c=a*b; //合取d=a+b; //析取e=(!a)+b; //条件式f=a*b+(!a)*(!b); //双条件式if(c==0) //化为逻辑值c=0;elsec=1;if(d==0)d=0;elsed=1;if(e=0)e=0;elsee=1;if(f==0)f=0;elsef=1;printf("\nthe logic value of hequ:%d\nthe logic value of xiqu:%d\nthe logic value of tiaojian:%d\nthe logic value of shuangtiaojian:%d\n",c,d,e,f);printf("do you want to continue?input 'y' continue");g=getch();{if(g=='y');else break;}}}2(B类)#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>typedef struct Node //二叉树节点结构体{char data; //存节点字符struct Node *leftchild;//左孩子指针struct Node *rightchild;//右孩子指针int temp;//判断该节点前是否有特别的字符类型}BeTreeNode;/*typedef struct{char stack[30];int top;}SeqStack;//账的结构体*/void print_char(BeTreeNode *root);void prints(BeTreeNode *p);char str[30]; //输入的字符串char S[16]; //仅存是字母的字符串int w,length,x=1; //分辨取哪一种真值赋值//SeqStack mystack;//定义一个栈BeTreeNode *pt[30];//定义指针数组int **S_num; //二维数组存真值的多种赋值情况int L=0;/*void StackInitiate(SeqStack *S) //初始化{S->top=0;}int StackNotEmpty(SeqStack S) //非空否{if(S.top<=0)return 0;else return 1;}int StackPush(SeqStack *S,char x)//入栈{if(S->top>=16){printf("堆栈已满无法插入!\n");return 0;}else{S->stack[S->top]=x;S->top++;return 1;}}*/BeTreeNode *MakeTree(int a,int b) //建立二叉树{int i,j=0,k=0,a1[10],b1[10];int L=0;BeTreeNode *p[10];BeTreeNode *pp,*sign=NULL;for(i=a;i<=b;i++)//若有括号的先渐入括号的最内层{if(str[i]=='('){//if(mystack.top==0)if(L==0)a1[j]=i;L++;}if(str[i]==')'){L--;if(L==0){b1[j]=i;p[j]=MakeTree(a1[j]+1,b1[j]-1);j++;} }}j=0;for(i=a;i<=b;i++,k++)//用指针来存储二叉树的每个节点{if(str[i]=='!'){if(str[i+1]=='('){ pt[k]=p[j];pt[k]->temp=2;i=b1[j];j=j+1;}else{pt[k]=(BeTreeNode *)malloc(sizeof(BeTreeNode)); pt[k]->data=str[i+1];pt[k]->leftchild=NULL;pt[k]->rightchild=NULL;pt[k]->temp=-1;i=i+1;}}else if(str[i]=='('){pt[k]=p[j];pt[k]->temp=1;i=b1[j];j=j+1;}else{ pt[k]=(BeTreeNode *)malloc(sizeof(BeTreeNode)); pt[k]->data=str[i];pt[k]->leftchild=NULL;pt[k]->rightchild=NULL;pt[k]->temp=0;}}pp=pt[0];for(i=1;i<k;i=i+2)//把各个二叉树的节点连接起来{if(pt[i]->data=='|'){pt[i]->leftchild=pp;pt[i]->rightchild=pt[i+1];pp=pt[i];}else{if(sign!=NULL){pt[i]->leftchild=sign;sign->rightchild=pp;pp=pt[i];sign=NULL;}else{pt[i]->leftchild=pp;pp=pt[i];}if(i+2<k){if(pt[i+2]->data=='|'){pp=pt[i+1];sign=pt[i];}else{pp->rightchild=pt[i+1];}}}}if(sign!=NULL){sign->rightchild=pp;pp=sign;}else pp->rightchild=pt[k-1];return pp;}void prints(BeTreeNode *p)//根据各个节点前的标记符的赋值确定应该要输出哪种字符{if(p->temp==2){printf("!(");print_char(p);printf(")");}else if(p->temp==1){printf("(");print_char(p);printf(")");}else if(p->temp==-1){printf("!");print_char(p);}elseprint_char(p);}void print_char(BeTreeNode *root)//输出某个节点下的树{if(root->leftchild==NULL&&root->rightchild==NULL){printf("%c",root->data);}else{prints(root->leftchild);printf("%c",root->data);prints(root->rightchild);}}void print(BeTreeNode *root)//利用二重循环来进行从最内层的子树开始输出,直到输出整棵树{if(root->leftchild->leftchild!=NULL)print(root->leftchild);if(root->rightchild->leftchild!=NULL)print(root->rightchild);if(root->leftchild->temp==-1)printf("!%c ",root->leftchild->data);if(root->rightchild->temp==-1)printf("!%c ",root->rightchild->data);print_char(root);if(root->temp==2){printf("");prints(root);}printf("");}int numre(char c)//输出叶节点{int i;for(i=0;i<length;i++){if(S[i]==c)return S_num[w][i];}}int Judge(int num1,char c,int num2)//判断最简单的表达式的返回值{if(c=='&'){if(num1==num2&&num1==1)return 1;else return 0;}if(c=='|'){if(num1==num2&&num1==0)return 0;else return 1;}}int print_num(BeTreeNode *root)//从最内层开始输出返回值{int num1,num2,num,i;char c;if(root->leftchild==NULL&&root->rightchild==NULL){num=numre(root->data);}else{num1=print_num(root->leftchild);c=root->data;num2=print_num(root->rightchild);if((root->leftchild->temp==2)||(root->leftchild->temp==-1)){ for(i=0;i<x;i++)printf("");printf(" %d",num1);}if((root->rightchild->temp==2)||(root->rightchild->temp==-1)){ for(i=0;i<x;i++)printf("");printf(" %d",num2);}num=Judge(num1,c,num2);for(i=0;i<x;i++)printf("");printf(" %d",num);x=x+3;}if((root->temp==2)||(root->temp==-1)){if(num==1)num=0;else num=1;}return num;}int fac(int t)//计算出2的n次方的结果{if(t==0)return 1;if(t==1)return 2;return 2*fac(t-1);}void S_numf(int n)//开辟一个二维数组存储真值表的各种赋值情况{int row,col,i,j,k,p;row=fac(n);col=n;S_num=(int *)malloc(sizeof(int)*row);for(i=0;i<row;i++){S_num[i]=(int *)malloc(sizeof(int)*col);}for(i=0;i<row;i++)for(j=0;j<col;j++)S_num[i][j]=0;for(i=0;i<col;i++)for(k=0,j=fac(i);k<fac(i);j++,k++){for(p=col-1;p>col-1-i;p--)S_num[j][p]=S_num[k][p];S_num[j][p]=1;}}main(){int i,j,LEN,t=0,temp=1;BeTreeNode *root;//定义根节点//StackInitiate(&mystack);printf("请输入一个符合命题公式(仅支持非'!',析取'|',合取'&',优先级:!,|,&)\n:");gets(str);LEN=strlen(str);for(i=0;i<LEN;i++){ for(j=0;j<t;j++)if(S[j]==str[i])temp=0;if((str[i]>='a'&&str[i]<='z'||str[i]>='A'&&str[i]<='Z')&&temp){S[j]=str[i];t++; }temp=1;}length=strlen(S);S_numf(length);root=MakeTree(0,LEN-1);printf("该复合命题公式的真值表是:\n");for(i=0;i<length;i++)printf("%c ",S[i]);print(root);printf("\n");for(w=0;w<fac(length);w++){for(i=0;i<length;i++)printf("%d ",S_num[w][i]);print_num(root);printf("\n");x=1;}}七收获与体会通过这次实验使我了解了一些数理逻辑问题可以通过用计算机编程的方法来解决,一些定理的证明同样也可以用计算机通过将命题符号化来编程解决。
C真值表实验报告
C++真值表实验报告实验1:真值表一、实验目的:通过试验,了解命题的有关概念,真值表技术,连接词的作用与意义二、实验类型:验证型实验三、实验学时:2学时四、实验原理及知识点掌握命题公式及其类型的概念,熟悉逻辑连接词的运算规则,熟悉命题公式真值表的构成,并可用计算机实现五、实验环境(硬件环境、软件环境)1、试验环境visual C++6.02、操作系统window 7六、实验内容及步骤1、编写操作界面使用MFC提供的DLG类,在面板上添加一个输入文本框作为输入公式的实例输入。
添加两个按钮分别表示在程序面板上显示结果和利用输出文本文件显示并保存结果。
2、按照运算规则编写求真值表函数在对应按钮的触发事件中添加对应的处理函数3、测试与修改七、思考与练习利用真值表技术和公式的演算方法,如何求得公式对应的主析取范式和主合取范式,如何判断两公式是否相等,是否为永真式、永假式、可满足式?附录A:#include <iostream> #include <stack> #include<cmath> #define maxsize 100 using namespace std;char str[100];//输入的表达式int zhipai[20]={0};//用于指派真值的数组int length;//逻辑表达式长度char expression[100];//用于计算的数组class symbol { public:void solve(); void Clear(){} private: void change(); int Calculate(); void check();bool Get2Operands(double &left,double &right); void DoOperator(char op);stack<int> s; //运算栈};bool symbol ::Get2Operands(double &left,double&right){ //取两运算值if(s.size()==0){ cerr<<"Miss Operand!"<<endl; return false;}right=s.top(); s.pop();if(s.size()==0){ cerr<<"Miss Operand!"<<endl;return false; }left=s.top(); s.pop(); return true;}void symbol ::DoOperator(char op){ //单次运算double left,right;bool result=Get2Operands(left,right);if(result)switch(op){case '|':s.push(left||right);break;//或运算case'&':s.push(left&&right);break;//与运算case '>':s.push(!left||right);break;//蕴涵运算case'!':s.push((!right)&&left);break;//非运算case '=':s.push(left==right);break;//等价运算}elseClear();}void symbol ::change() //将输入的字符串转化为可计算的表达式{ int k=0; int flag=1;int count=0; //命题变元个数for(inti=0;i<pow(2,count);i++) { k=1;for(int m=0;m<length;m++) { if(isalpha(str[m]))//将原来的命题变元修改为真值{ if(flag==1) {if(zhipai[k]==0) expression[m]='0'; elseexpression[m]='1'; k++; } elseexpression[m]='0'; flag=1;for(int t=m;t>=0;t--){if((str[m+1]==str[t])&&isalpha(str[m+1])&&isalpha(s tr[t])) flag=0; } }elseexpression[m]=str[m];//逻辑联结词不变}for(int t=0;t<length;t++) { for(int j=t;j<length;j++) { if(str[t]==str[j]){expression[j]=expression[t];//相同的命题变元复制赋值}} } } }void plus(int a[],int q)//二进制加法器,用于指派真值{ a[q]=a[q]+1;for(int i=q;a[i]==2;i--) { a[i]=0;a[i-1]=a[i-1]+1;} }int isp(char ch){ //联结词的栈内优先级switch(ch){case '#':return 0;break; case '(':return1;break; case '!':return 10;break; case'=':return 9;break; case '&':return 7;break; case '|':return 5;break; case '>':return 3;break; case ')':return 12;break; default:return -1;break;}}int icp(char ch){ //联结词的栈外优先级switch(ch){case '#':return 0;break; case '(':return12;break; case '!':return 11;break; case'=':return 8;break; case '&':return 6;break; case '|':return 4;break; case '>':return 2;break; case ')':return 1;break; default:return -1;break;}}int symbol ::Calculate(){ //模仿实数加法器进行表达式计算stack<char> h;//联结词栈char ch,y; h.push('#');for(int temp=0;temp<length-1;temp++){ ch=expression[temp];if(isdigit(ch))//命题变元真值入栈{ if(ch=='0') s.push(0); elses.push(1);}else if(ch==')')//运算括号内的{for(y=h.top(),h.pop();y!='(';y=h.top(),h.pop()){DoOperator(y);}}else{ if(ch=='!')//非运算,在!前加1,将!视作双目操作符{ s.push(1);}for(y=h.top(),h.pop();isp(y)>icp(ch);y=h.top(),h.pop())//联结词入栈DoOperator(y); h.push(y);h.push(ch);} }while(h.size()!=1){//计算剩下的y=h.top(); h.pop();DoOperator(y);}cout <<s.top()<<endl;//输出最终结果return s.top(); }void symbol::check();//检查函数的预先声明void symbol::solve()//问题的解决{ cout<<" 使用说明"<<endl;cout<<" ———————"<<endl;cout<<"=================================hx1.push('('); stack<char> hx2;for(int r=0;r<pow(2,count);r++)//输出真值表================="<<endl;cout<<"=={=="<<endl; for(int j=1;j<=count;j++) cout<<"== 命题变元个数不要超过20个{cout<<zhipai[j]<<' ';} =="<<endl;cout<<"== 或运算用'|' 与运算用'&' =="<<endl;cout<<"== 非运算用'!' 蕴涵运算用'>' =="<<endl;cout<<"== 等价运算用'=' 表达式以#结尾== "<<endl;cout<<"===="<<endl;cout<<"=================================================="<<endl;cout<<"请输入命题逻辑表达式:";int flag=1;//标记,防止重复添加命题变元int count=0;//命题变元的数目cin >>str; //输入命题逻辑表达式length=strlen(str);char bianyuan[100]; //命题变元数组for(int i=0;i<length;i++)//逐次添加命题变元{if(isalpha(str[i])&&(flag==1)){bianyuan[count]=str[i];count++;}flag=1;for(int k=0;k<count;k++){if(bianyuan[k]==str[i+1])flag=0;}}if(count==0){cout<<"无命题变元,重新输入!"<<endl;solve();}check();//合法性检查cout<<"真值表:" <<endl;for(int w=0;w<count;w++)cout<<bianyuan[w]<<' ';cout<<"fc"<<endl;int* truth=new int[pow(2,count)];stack<char> xh1;xh1.push('(');stack<char> xh2;stack<char> hx1; change(); truth[r]=Calculate();if(truth[r]==1) //成真指派入析合栈{ for(intt=0;t<count;t++) { if(zhipai[t+1]==1){ xh1.push(bianyuan[t]); xh1.push('&'); } else { xh1.push('!'); xh1.push(bianyuan[t]); xh1.push('&'); } } xh1.pop();xh1.push(')'); xh1.push('|');xh1.push('('); } if(truth[r]==0) //成假指派入合析栈{ for(int c=0;c<count;c++) { if(zhipai[c+1]==1){ hx1.push(bianyuan[c]); hx1.push('|'); }else { hx1.push('!'); hx1.push(bianyuan[c]); hx1.push('|'); } } hx1.pop();hx1.push(')'); hx1.push('&');hx1.push('(');}plus(zhipai,count);}cout<<"是否继续运算?Y/N"<<endl; char goon;cin>>goon;if(goon=='y'||goon=='Y') { system("cls");solve();//递归调用solve,重新计算} else exit(0); }void symbol::check()//检查输入的逻辑表达式是否合法{ if(str[length-1]!='#'){cout<<"未以#结尾,重新输入!"<<endl;solve();}if(!isalpha(str[length-2])&&str[length-2]!=')'){cout&l t;<"错误,重新输入!"<<endl;solve();} for(inti=0;i<length-1;i++) {if(!isalpha(str[i])&&str[i]!='&'&&str[i ]!='|'&&str[i]!='>'&&str[i]!='='&&str[i]!='!& #39;&&str[i]!='('&&str[i]!=')') { cout<<"错误的字符,重新输入!"<<endl;solve(); } if(isalpha(str[i])&&str[i+1]=='!'){cout<<"命题变元后不可跟!,重新输入!"<<endl;solve();}if(str[i]==')'&&str[i+1]=='!'){cout<<")后不可跟!,重新输入!"<<endl;solve();}if(isalpha(str[i])&&isalpha(str[i+1])){cout<<"命题变元之间无联结词,重新输入!"<<endl;solve();}if(isalpha(str[i])&&str[i+1]=='('){cout<<"命题变元后不可接(,重新输入!"<<endl;solve();}if(!isalpha(str[i])&&!isalpha(str[i+1])&&(str[i]!=' ;('&&str[i+1]!='!')&&str[i+1]!='('&&str[i]!=')'){ cout<<"联结词间无命题变元,重新输入!"<<endl;solve(); }}int left=0,right=0,j=0;while(j<length-1){ if(str[j]=='(') left++; if(str[j]==')') right++; if(right>left){cout<<"括号次序不匹配,重新输入!"<<endl;solve();} j++; }if(left!=right){cout<<"括号个数不匹配,重新输入!"<<endl;solve();} }int main(){ symbol a;//对象aa.solve();//调用a的函数solve,实现功能return 0;}附录B:。
离散数学实验报告(一)
一、实验内容:构造任意合式公式的真值表二、实验源码:#include <stdio.h>#include"thesis.h"int main(){Thesis a[30];char x='1';int i=0,N;cout<<"请输入命题变元(不超过30个)(输入'0'结束输入):"<<endl;while(int(x)!=48){cin>>x;if(i>19){cout<<"Error:变元个数太多!"<<endl;break;}if(x!='0'){a[i].inname(x);i++;}}N=i;int M;M=N;string A;cout<<"请输入命题公式( 否定:!,合取:&,析取:| )"<<endl;cin>>A;cout<<A<<"的真值表为:"<<endl;for(int j=0;j<M;j++)cout<<char(a[j].getvalue())<<" ";cout<<"真值"<<endl;assignment(A,N,M,&a[0]);system("pause");return 0;}#include"thesis.h"头文件#ifndef THESIS_H#define THESIS_H#include<string>#include<stdlib.h>#include<iostream>using namespace std;class Thesis //命题类{int value;char name; //value:命题的真值(0/1)name:命题名public:Thesis(){value=2;name='A';};friend Thesis operator !(Thesis &q){q.invalue(1-q.getvalue()); return q;} //重载逻辑运算符friend Thesis operator &(Thesis &p,Thesis &q){p.invalue((p.getvalue()+q.getvalue())/2); return p;}friend Thesis operator |(Thesis &p,Thesis &q){if(p.getvalue()+q.getvalue()>0) p.invalue(1);else p.invalue(0);return p;}friend Thesis operator >(Thesis &p,Thesis &q){if(p.getvalue()==1&&q.getvalue()==0)p.invalue(0);else p.invalue(1);return p;}friend Thesis operator <(Thesis &p,Thesis &q){if(p.getvalue()==q.getvalue()) p.invalue(1);else p.invalue(0);return p;}void invalue(int x){value=x;} //输入valuevoid inname(char x){name=x;} //输入nameint getvalue(){return value;} //获取真值int getname(){return name;} //获取命题名};void assignment(string A,int N,int M,Thesis a[]); //声明函数int bds(string A,int N,Thesis a[]);int run(string A,int &i,int L,int N,Thesis a[]);void assignment(string A,int N,int M,Thesis a[])//命题赋值并计算真值{for(int j=0;j<2;j++){a[N-1].invalue(j);if(N>1){assignment(A,N-1,M,&a[0]);}else{for(int i=0;i<M;i++){cout<<a[i].getvalue()<<" ";}cout<<bds(A,M,&a[0])<<endl;}}}int bds(string A,int N,Thesis a[]) //识别输入的表达式并计算真值{Thesis answer,Temp;char d[5]={'!','|','&','>','<'}; //定义运算符号集合int L;int i=0;L=strlen(&A[0]); //表达式长度while(i<L){if(A[i]=='('){int k=1;for(int j=i+2;j<L;j++){if(k!=0){if(A[j]=='(')k++;if(A[j]==')')k--;}if(k==0){int l=j-i-1;char *p=new char[l+1];string B;for(int m=0;m<l;m++)p[m]=A[i+1+m];p[l]='\0';B=p;delete p;Temp.invalue(bds(B,N,&a[0]));if(i==0)answer.invalue(Temp.getvalue());i=j+1;break;}}}else{if(A[i]=='!') //否定的计算{Temp.invalue(run(A,i,L,N,&a[0]));answer=!Temp;i++;continue;}else if(A[i]=='|'){Temp.invalue(run(A,i,L,N,&a[0]));answer=answer|Temp;i++;continue;}else if(A[i]=='&'){Temp.invalue(run(A,i,L,N,&a[0]));answer=answer&Temp;i++;continue;}else if(A[i]=='<'){Temp.invalue(run(A,i,L,N,&a[0]));answer=answer<Temp;i++;continue;}else if(A[i]=='>'){Temp.invalue(run(A,i,L,N,&a[0]));answer=answer>Temp;i++;continue;}else{for(int j=0;j<N;j++){if(A[i]==char(a[j].getname())){Temp.invalue(a[j].getvalue());if(i==0)answer.invalue(Temp.getvalue());i++;break;}}}}}return answer.getvalue();}int run(string A,int &i,int L,int N,Thesis a[]) {Thesis Temp;if(A[i+1]=='('){int k=1;for(int j=i+2;j<L;j++){if(k!=0){if(A[j]=='(')k++;if(A[j]==')')k--;}if(k==0){int l=j-i-1;char *p=new char[l+1];string B;for(int m=0;m<l-1;m++)p[m]=A[i+2+m];p[l-1]='\0';B=p;delete p;Temp.invalue(bds(B,N,&a[0]));i=i+j;break;}}}else{int j=0;while(j<L){if(A[i+1]==char(a[j].getname())){i++;Temp=a[j];break;}j++;}}return Temp.getvalue(); }#endif三、运行结果。
离散实验
实验一 命题逻辑
char first(char op1, char op2)//根据输入的两个关联词,查找他们的优先级关系 { char tab[8][9]={ "><<<<<>>", ">><<<<>>", ">>><<<>>", ">>>><<>>", ">>>>><>>", "<<<<<<=E", ">>>>>E>>", "<<<<<<E=",}; char optr_list[]="+-|&!()@";//双条件、条件、析取、合取、非 int op1_loc, op2_loc; for(op1_loc=0;op1_loc<(int)strlen(optr_list);op1_loc++)if(optr_list[op1_loc]==op1)br eak; for(op2_loc=0;op2_loc<(int)strlen(optr_list);op2_loc++)if(optr_list[op2_loc]==op2)br eak; return tab[op1_loc][op2_loc];}
实验一 命题逻辑
中南大学离散数学实验分析方案(实验ABC)
“离散数学”实验报告(实验1ABC>专业班级学号姓名日期:2018.12.05目录一、实验目的3二、实验内容3三、实验环境3四、实验原理和实现过程<算法描述)31、实验原理32、实验过程4五、实验数据及结果分析7A题型7B、C题型9六、源程序清单13A题部分源代码13B、C题部分源代码14七、其他收获及体会22一、实验目的熟悉掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
二、实验内容1. 从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、条件和双条件的真值。
<A)2. 求任意一个命题公式的真值表<B,并根据真值表求主范式<C))三、实验环境C或C++语言编程环境实现。
四、实验原理和实现过程<算法描述)1.实验原理<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)双条件:二元命题联结词。
离散数学实验——真值表
#include<iostream.h>void main(){ int m,s;char a,b,c,d,e;do{cout<<"\n ********欢迎进入该系统******** "<<"\n";cout<<" 1.与运算p&&q "<<"\n";cout<<"2.或运算p||q "<<"\n";cout<<"3.非运算!q "<<"\n";cout<<" 4.则运算p->q "<<"\n";cout<<”5.蕴涵运算p<->q "<<"\n\n";cout<<"请选择你需要的操作序号: ";cin>>m;switch (m) {case 1:{cout<<"\n请输入两个字母:";cin>>a>>b;cout<<a<<"\t"<<b<<"\t"<<a<<"&&"<<b<<"\n";for(int i=0;i<2;i++)for(int k=0;k<2;k++){ c out<<i<<"\t"<<k<<"\t";if(i+k==2) cout<<"1"<<"\n";elsecout<<"0"<<"\n";}break; }case 2:{cout<<"\n请输入两个字母:";cin>>c>>d;cout<<c<<"\t"<<d<<"\t"<<c<<"||"<<d<<"\n";for(int j=0;j<2;j++)for(int k=0;k<2;k++){ cout<<j<<"\t"<<k<<"\t";if(j+k>0)cout<<1<<"\n";else cout<<0<<"\n";}break; }case 3:{cout<<"\n请输入一个字母:";cin>>e;cout<<e<<"\t"<<"!"<<e<<"\n";for(int j=0;j<2;j++){ cout<<j<<"\t";if(j==0)cout<<1<<"\n";elsecout<<0<<"\n";}break; }case 4:{cout<<"\n请输入两个字母:";cin>>a>>b;cout<<a<<"\t"<<b<<"\t"<<a<<"->"<<b<<"\n";for(int j=0;j<2;j++)for(int k=0;k<2;k++){ cout<<j<<"\t"<<k<<"\t";if(j==0)cout<<1<<"\n";else{if(k==1)cout<<1<<"\n";elsecout<<0<<"\n";} }break;}case 5:{cout<<"\n请输入两个字母:";cin>>a>>b;cout<<a<<"\t"<<b<<"\t"<<a<<"<->"<<b<<"\n";for(int j=0;j<2;j++)for(int k=0;k<2;k++){ cout<<j<<"\t"<<k<<"\t";if(j==k)cout<<1<<"\n";elsecout<<0<<"\n";}break;}}cout<<"\n 你还需要继续操作吗?(YES=1,NO=0): ";cin>>s;}while(s);}1运算:a&&b2运算:p->q3运算:c<—>d。
计算命题演算公式真值(数据结构C语言版)实习报告
计算命题演算公式的真值李仙伟 014072-281.需求分析1.1.命题演算公式由逻辑变量(其值为TRUE或FALSE)和逻辑运算符∧(AND)、∨(OR)和┐(NOT)按一定规则所组成的公式。
公式运算的先后顺序为┐、∧、∨,而括号()可以改变优先次序。
1.2.输入输出以人机对话的方式让用户输入要计算的命题表达式;计算出最后的真值并输到屏幕上。
1.3.测试数据:①~((~a&b)|c)&d②~(boy&girl)|father)&mother③(5&~99)|02.概要设计2.1.基本思想:①利用二叉树计算公式的真值:第一步:利用堆栈将中缀形式的公式变为后缀形式;第二步:根据后缀形式,从叶结点开始构造相应的二叉树;第三步:按后序遍历该树,求各子树之值,即每到达一个结点,其子树之值已经计算出来,当到达根结点时,求得的值就是公式之真值;②逻辑变元的标识符不限于单字母,而可以是任意长的字母数字串;③根据用户的要求显示表达式的真值表。
2.2.程序设计的概要图如下所示:2.3.抽象数据类型的定义及其相应的操作函数定义如下:①/*定义一个堆栈SeqStack1,用来实现将输入的中缀表达式转换为后缀表达式*/typedef char DataType ;typedef struct{DataType stack[MaxStackSize];int top;}SeqStack1;/*初始化SeqStack1,栈底为‘#’*/void StackInitiate1(SeqStack1 *S)/*将元素压入SeqStack1*/void StackPush1(SeqStack1 *S,DataType x)/* SeqStack1出栈*/void StackPop1(SeqStack1 *S,DataType *x)/*取SeqStack1的栈顶元素*/int StackTop1(SeqStack1 S,DataType *d)②/*定义链式堆栈LSNode,用于检测表达式的括号匹配*/typedef struct snode{DataType data;Struct snode *next;}LSNode;/*初始化堆栈LSNode*/void StackInitiate(LSNode** head)/*判断堆栈LSNode是否为空的函数,空返回0,否则返回1*/int StackNotEmpty(LSNode*head)/*LSNode入栈函数*/int StackPush(LSNode* head,DataType x)/*LSNode出栈函数*/int StackPop(LSNode* head,DataType* d)/*LSNode取栈顶元素*/int StackTop(LSNode* head,DataType *d)/*撤消LSNode动态申请空间*/void Destroy(LSNode* head)③/*检测输入表达式的括号匹配函数*/void ExpIsCorrect(char exp[])④/*定义二叉树的结点BiTreeNode*/typedef struct Node{DataType data[MaxStackSize];struct Node *leftChild;struct Node *rightChild;struct Node *parent;}BiTreeNode;/*初始化BiTreeNode的根结点*/void Initiate(BiTreeNode **root) /*将BiTreeNode结点压入堆栈2*/void StackPush2(SeqStack2 *S,BiTreeNode *x)/*逆时针打印BiTreeNode */void print(BiTreeNode *bt,int n)⑤/*定义一个顺序堆栈SeqStack2,用于构造二叉树时对结点的保存*/typedef struct{BiTreeNode * Save[MaxStackSize];int top;}SeqStack2;/*初始化SeqStack2*/void StackInitiate2(SeqStack2 *S)/*SeqStack2出栈*/BiTreeNode * StackPop2(SeqStack2 *S)⑥/*将待求表达式子转换为后缀形式*/int Convert(char a[MaxSize1],char b[MaxSize1][MaxSize2],SeqStack1 *S,int n)⑦/*根据上面转换的表达式的后缀形式,构造相应的二叉树*/BiTreeNode * BuildTree(char b[MaxSize1][MaxSize2],int n)⑧/*后序遍历该树,并且每到达一个结点时候,计算其子树之值,当到达根结点时,求得的值就是公式之真值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
离散数学实验报告
专业班级:12级计算机本部一班姓名:鲍佳珍
学号:201212201401016 实验成绩:
1.【实验题目】
命题逻辑实验二
2.【实验目的】
熟悉掌握命题逻辑中真值表,进一步能用它们来解决实际问题。
3.【实验内容】
求任意一个命题公式的真值表
4、【实验要求】
C或C++语言编程实现
5. 【算法描述】
1.实验原理
真值表:表征逻辑事件输入和输出之间全部可能状态的表格。
列出命题公式真假值的表。
通常以1表示真,0 表示假。
命题公式的取值由组成命题公式的命题变元的取值和命题联结词决定,命题联结词的真值表给出了真假值的算法。
真值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。
2.实验过程
首先是输入一个合理的式子,生成相应真值表,然后用函数运算,输出结果:要求可生成逻辑非、合取、析取、蕴含、双条件表达式的真值表,例如:输入 !a
输出真值表如下:
a !a
0 1
10
输入a&&b
输出真值表如下:
a b a&&b
0 0 0
0 1 0
1 0 0
1 1 1
输入a||b
输出真值表如下:
a b a||b
0 0 0
0 1 1
1 0 1
1 1 1
输入a->b
输出真值表如下:
a b a->b
0 0 1
0 1 1
1 0 0
1 1 1
输入a<>b (其中<>表示双条件) 输出真值表如下:
a b a<>b
0 0 1
0 1 0
1 0 0
1 1 1
6.【源程序(带注释)】
#include<stdio.h>
#include<string.h>
void hequ();
void yunhan();
void xiqu();
void shuang();
void fei();//声明五个函数
int main()
{
int ch;
char s[10];
printf("欢迎使用命题公式真值表查找软件\n\n");
printf("1.合取 2.析取 3.蕴含 4.双条件 5.非0.结束查找\n");//软件使用界面的输出
scanf("%d",&ch);
while(ch){
printf("\n\n您能查找真值表的命题公式有以下几种:\n\n");
printf("1.合取请输入a&&b 2.析取请输入a||b 3.蕴含请输入a->b 4.双条件请输入a<>b 5.非请输入!a\n");//选择输入的公式类型
getchar();
printf("请输入您所需要查询的公式:");
scanf("%s",s);
if(!strcmp(s,"a&&b"))
hequ();
else if(!strcmp(s,"!a"))
fei();
else if(!strcmp(s,"a||b"))
xiqu();
else if(!strcmp(s,"a->b"))
yunhan();
else if(!strcmp(s,"a<>b"))//将输入的公式与程序内存在的公式进行比较
shuang();
else
printf("对不起,您所要查找的公式不存在!\n\n");
printf("\n 1.继续查找0.结束\n\n");
scanf("%d",&ch); //使程序循环
}
return 0;
}
void hequ()
{
printf("a b a&&b\n");
printf("0 1 0\n");
printf("0 0 0\n");
printf("1 0 0\n");
printf("1 1 1\n");
}
void xiqu()
{
printf("a b a||b\n");
printf("0 1 1\n");
printf("1 0 1\n");
printf("1 1 1\n"); }
void yunhan()
{
printf("a b a->b\n");
printf("0 1 1\n");
printf("0 0 1\n");
printf("1 0 0\n");
printf("1 1 1\n"); }
void fei()
{
printf("a !a\n");
printf("1 0\n");
printf("0 1\n");
}
void shuang()
{
printf("a b a<>b\n");
printf("0 1 0\n");
printf("1 0 0\n");
printf("1 1 1\n");
} //定义五个函数
7.【实验结果与分析总结(含运行结果截图)】输入界面
输入公式并输出真值表
继续查找结束程序。