离散数学上机实验,给定一个命题公式,求其主析取范式,主合取范式,能力有限,参考了我学长的一篇博客,并进行了许多优化。

本次离散数学实验,我学到了许多东西,也看了自己的不足之处

1).我深刻地体会到在比较大型的软件的开发过程中预先进行设计的重要性,就拿这个小程序来说,

如果不预先设计好程序需要的算法,各个函数,解决方法的一步步流程,那么在真正开发过程中效率将大大降低,会不断地删除修改,有时候甚至要重写,这都是事先没有进行计划的原因。

2).程序设计中算法的重要性,本程序用到了将命题公式转化为逆波兰表达式的算法,我起先一点也不会,但是看了学长的源代码理解了个大概,自己又仔细琢磨琢磨,也就写出来了,但是现在让我独立再写一遍我是真的 写不出来了

3).大型程序中函数名称的规范性,起先我嫌弃命名规范的话敲起代码来很不舒服,可是随着程序越来越大,程序变得越来越难读,最终我全部换成了能一眼看出功能函数名

4).要学会版本控制系统

各个版本原代码:各个版本代码

#include <cstdio>
#include <cstring>
#include <windows.h>
#include <iostream>
using namespace std;string Original_Formula;//用户输入的命题公式
string Simp_Formula;//将用户输入的命题公式中->和<->转化为>和~
string Suffix_Formula;//将简化后的式子转化为后缀表达式
string PCNF;//主合取范式
string PDNF;//主析取范式char ch[15]="()PQRST!&|-><";//把用户输入的式子简化时需要该语句int p,q,r,s,t;//for循环打印真值表时使用
int a,b,res;//逻辑运算时使用,比如a==1, b==0传到了And()(合取函数)里,这时候res为0;
int v=0;//还未写注释
int var_cnt;//计算用户输入的变量的个数(各不相同的变量的个数,重复的算一个)//用一个类来模拟栈
class  Stack
{
public:Stack(int mSize){maxtop=mSize-1; //maxtop为st数组下标最大值,mSize为st数组元素个数st=new char[mSize];//动态内存分配top=-1;}~Stack()//析构函数,释放st[]内存{delete[]st;}bool Push(char x)//模拟入栈{if(top==maxtop)//如果栈溢出,返回falsereturn false;st[++top]=x;return true;}bool Pop(){if(top==-1)return false;top--;//模拟出栈return true;}char Top(){return st[top];//模拟取栈顶元素}
private:int top;char *st;int maxtop;
};void Not();//非运算
void And();//合取运算
void Or();//析取运算
void If();//条件运算
void Iif();//双条件运算
void Menu();//打印菜单,增强用户体验
void count_varcnt();计算用户输入的变量的个数(各不相同的变量的个数,重复的算一个)
void InputANDjude_formula();// 用户输入的命题公式并进行检查,如果有异常输入,输出警告,并重新输入
bool Jude_canin(char);//判断运算符能否入栈
void Change_to_sufexp();//将处理后的命题公式转化为逆波兰表达式
void Calculate();//进行逻辑运算
void Print();//打印结果
void Not_Not(char);//忘记了,稍后补回来
void Switch_Operator(char);//运算符优先级,判断能否进栈
bool Enh_Robustness();//增强程序鲁棒性
Stack Sim_stack(200);//构造一个类对象,Sim_stackint main()
{HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//Windows编程的小知识,看不懂的话可以将这样的语句全部删除不影响,这些全部用来控制窗口文字的颜色Menu();//输出菜单while(1){do{InputANDjude_formula();//当检测到用户非法输入时,让用户再次输入}while(!Enh_Robustness());if(Original_Formula=="Over")//用户输入Over可结束程序{SetConsoleTextAttribute(hConsole, 0xC );cout<<"\\\\*^o^*// 谢谢使用 \\\\*^o^*//"<<endl;SetConsoleTextAttribute(hConsole, 0xF );system("pause");return 0;}count_varcnt();//计算出用户输入的变量的个数Change_to_sufexp();//将处理后的命题公式转化为逆波兰表达式Print();//打印}return 0;
}
/***********************************打印菜单*********************************************/
void Menu()
{HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hConsole, 0xB );cout<<"******************离散数学之数理逻辑******************"<<endl;cout<<"******************    输入符号规定  ******************"<<endl;cout<<"******************      ┐:!        ******************"<<endl;cout<<"******************      ∧:&        ******************"<<endl;cout<<"******************      ∨:|        ******************"<<endl;cout<<"******************      →:->       ******************"<<endl;cout<<"******************      ←→:<->    ******************"<<endl;cout<<"******************************************************"<<endl;cout<<endl;SetConsoleTextAttribute(hConsole, 0xC );cout<<"必读:1.支持括号"<<endl;cout<<"     2.最多支持五个不同变元(P,Q,R,S,T),最少两个变元"<<endl;cout<<"     3.两个变元用P,Q;三个用P,Q,R:以此类推"<<endl;cout<<"     3.输入时请注意大小写及英文状态下输入符号"<<endl;cout<<"     4.十分感谢我校***学长的热心指导"<<endl;cout<<"     5.时间仓促,程序可能存在bug,如有发现请及时告知,十分感谢"<<endl;cout<<"     6.2016.3  12-17   By:********   ****1.8版本****"<<endl;cout<<"\n"<<endl;SetConsoleTextAttribute(hConsole, 0xF );
}
/***********************************打印菜单*********************************************//*************************输入并且进行简化************************************************/
void InputANDjude_formula()
{char str1[100]={0}, str2[100], str3[100]; //str1为输入式子,str2为处理后的式子,并将处理后的式子赋给Simp_Formulaint cnt=0;cout<<"请输入命题公式:(输入Over可结束程序)"<<endl;gets(str1);                        //疑惑:将str1, str2改为全局变量后程序出错   要用gets(),不然鲁棒性不强for(int i=0;i<strlen(str1);)//将用户输入的命题公式中->和<->转换成>和<{if(str1[i]=='-') { str2[cnt++]='>';i+=2; }else if(str1[i]=='<') { str2[cnt++]='~';i+=3; }else  { str2[cnt++]=str1[i];i+=1; }}str2[cnt++]='\0';//重要,给字符串加上结束标记符Original_Formula=str1;Simp_Formula=str2;
}
/*************************输入并且进行简化************************************************//*************************增强程序鲁棒性**************************************************/
bool Enh_Robustness()
{bool Rob=true;if(Original_Formula=="Over")return true;for(int i=0;i<Original_Formula.length();i++){if(strchr(ch,Original_Formula[i])==NULL){HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hConsole, 0xC );cout<<"输入异常,请检查是否有空格,小写抑或非法字符"<<endl<<endl;SetConsoleTextAttribute(hConsole, 0xF );Original_Formula="";return false;}}return Rob;}
/*************************增强程序鲁棒性**************************************************//********************************计算出用户输入的变量的个数*******************************/
void count_varcnt()
{int Count=0;bool P=true, Q=true, R=true, S=true, T=true;for(int i=0;i<Simp_Formula.length();i++){if(Simp_Formula[i]=='P'&&P) { Count++; P=!P; }else if(Simp_Formula[i]=='Q'&&Q) { Count++; Q=!Q; }else if(Simp_Formula[i]=='R'&&R) { Count++; R=!R; }else if(Simp_Formula[i]=='S'&&S) { Count++; S=!S; }else if(Simp_Formula[i]=='T'&&T) { Count++; T=!T; }else  continue;}var_cnt=Count;
}
/********************************计算出用户输入的变量的个数*******************************//********************************优先级运算***********************************************/
bool Jude_canin(char out)//具体的大家代入数据实际体验体验
{char in=Sim_stack.Top();int i, o;switch(in){case '#':i=0; break;case '(':i=1; break;case '~':i=3; break;case '>':i=5; break;case '|':i=7; break;case '&':i=9; break;case '!':i=11; break;case ')':i=12; break;}switch(out){case '#':o=0; break;case '(':o=12; break;case '~':o=2; break;case '>':o=4; break;case '|':o=6; break;case '&':o=8; break;case '!':o=10; break;case ')':o=1; break;}if(i<o)return true;elsereturn false;
}
/********************************优先级运算***********************************************//*******************************将处理后的命题公式转化为逆波兰表达式**********************/
void Change_to_sufexp()
{string Tmp="";Sim_stack.Push('#');for(int i=0;i<Simp_Formula.length();i++){if(Simp_Formula[i]=='P'||Simp_Formula[i]=='Q'||Simp_Formula[i]=='R'||Simp_Formula[i]=='S'){Tmp=Tmp+Simp_Formula[i];continue;}if(Jude_canin(Simp_Formula[i]))Sim_stack.Push(Simp_Formula[i]);else if(Simp_Formula[i]==')'){while(Sim_stack.Top()!='('){Tmp=Tmp+Sim_stack.Top();Sim_stack.Pop();}Sim_stack.Pop();}else{do{Tmp=Tmp+Sim_stack.Top();Sim_stack.Pop();}while(!Jude_canin(Simp_Formula[i]));Sim_stack.Push(Simp_Formula[i]);}}while(Sim_stack.Top()!='#'){Tmp=Tmp+Sim_stack.Top();Sim_stack.Pop();}Sim_stack.Pop();Suffix_Formula=Tmp;
}
/*******************************将处理后的命题公式转化为逆波兰表达式**********************//*******************************进行运算**************************************************/
void Calculate()
{if(var_cnt==2){for(int i=0;i<Suffix_Formula.length();i++){if(Suffix_Formula[i]=='P'||Suffix_Formula[i]=='Q'){v= Suffix_Formula[i]=='P'?p:q;Sim_stack.Push(v);continue;}Not_Not(Suffix_Formula[i]);Switch_Operator(Suffix_Formula[i]);}}if(var_cnt==3){for(int i=0;i<Suffix_Formula.length();i++){if(Suffix_Formula[i]=='P'||Suffix_Formula[i]=='Q'||Suffix_Formula[i]=='R'){v= Suffix_Formula[i]=='P'?p:Suffix_Formula[i]=='Q'?q:r;Sim_stack.Push(v);continue;}Not_Not(Suffix_Formula[i]);Switch_Operator(Suffix_Formula[i]);}}if(var_cnt==4){for(int i=0;i<Suffix_Formula.length();i++){if(Suffix_Formula[i]=='P'||Suffix_Formula[i]=='Q'||Suffix_Formula[i]=='R'||Suffix_Formula[i]=='S'){v= Suffix_Formula[i]=='P'?p:Suffix_Formula[i]=='Q'?q:Suffix_Formula[i]=='R'?r:s;Sim_stack.Push(v);continue;}Not_Not(Suffix_Formula[i]);Switch_Operator(Suffix_Formula[i]);}}if(var_cnt==5){for(int i=0;i<Suffix_Formula.length();i++){if(Suffix_Formula[i]=='P'||Suffix_Formula[i]=='Q'||Suffix_Formula[i]=='R'||Suffix_Formula[i]=='S'||Suffix_Formula[i]=='T'){v= Suffix_Formula[i]=='P'?p:Suffix_Formula[i]=='Q'?q:Suffix_Formula[i]=='R'?r:Suffix_Formula[i]=='S'?s:t;Sim_stack.Push(v);continue;}Not_Not(Suffix_Formula[i]);Switch_Operator(Suffix_Formula[i]);}}
}
/*******************************进行运算**************************************************//********************************打印*****************************************************/
void Print()
{if(var_cnt==2){cout<<"真值表如下"<<endl;cout<<"P\t"<<"Q\t"<< Original_Formula<<endl;for(p=1;p>=0;p--){for(q=1;q>=0;q--){Calculate();if(res==1)PDNF=PDNF+"("+(p==1?"P":"┐P")+"∧"+(q==1?"Q":"┐Q")+")"+"∨";elsePCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+")"+"∧";cout<<p<<"\t"<<q<<"\t"<<res<<endl;}}}if(var_cnt==3){cout<<"真值表如下"<<endl;cout<<"P\t"<<"Q\t"<<"R\t"<< Original_Formula<<endl;for(p=1;p>=0;p--){for(q=1;q>=0;q--){for(r=1;r>=0;r--){Calculate();if(res==1)PDNF=PDNF+"("+(p==1?"P":"┐P")+"∧"+(q==1?"Q":"┐Q")+"∧"+(r==1?"R":"┐R")+")"+"∨";elsePCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+")"+"∧";cout<<p<<"\t"<<q<<"\t"<<r<<"\t"<<res<<endl;}}}}if(var_cnt==4){cout<<"真值表如下"<<endl;cout<<"P\t"<<"Q\t"<<"R\t"<<"S\t"<<Original_Formula<<endl;for(p=1;p>=0;p--){for(q=1;q>=0;q--){for(r=1;r>=0;r--){for(s=1;s>=0;s--){Calculate();if(res==1)PDNF=PDNF+"("+(p==1?"P":"┐P")+"∧"+(q==1?"Q":"┐Q")+"∧"+(r==1?"R":"┐R")+"∧"+(s==1?"R":"┐R")+")"+"∨";elsePCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+"∨"+(s==0?"R":"┐R")+")"+"∧";cout<<p<<"\t"<<q<<"\t"<<r<<"\t"<<s<<"\t"<<res<<endl;}}}}}if(var_cnt==5){cout<<"真值表如下"<<endl;cout<<"P\t"<<"Q\t"<<"R\t"<<"S\t"<<"T\t"<<Original_Formula<<endl;for(p=1;p>=0;p--){for(q=1;q>=0;q--){for(r=1;r>=0;r--){for(s=1;s>=0;s--){for(t=1;t>=0;t--){Calculate();if(res==1)PDNF=PDNF+"("+(p==1?"P":"┐P")+"∧"+(q==1?"Q":"┐Q")+"∧"+(r==1?"R":"┐R")+"∧"+(s==1?"R":"┐R")+")"+"∨";elsePCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+"∨"+(s==0?"R":"┐R")+")"+"∧";cout<<p<<"\t"<<q<<"\t"<<r<<"\t"<<s<<"\t"<<t<<"\t"<<res<<endl;}}}}}}if(PDNF.length()==0)cout<<"主析取范式不存在"<<endl;else{PDNF.erase(PDNF.length()-2);cout<<"主析取范式为:"<<PDNF<<endl<<endl;}if(PCNF.length()==0)cout<<"主合取范式不存在"<<endl;else{PCNF.erase(PCNF.length()-2);cout<<"主合取范式为:"<<PCNF<<endl<<endl;}PDNF="";PCNF="";
}
/********************************打印*****************************************************/void Not_Not(char c)//功能:判断运算符是否为!,为什么呢?因为如果是!,我只需取一个元素
{                   //否则的话我必须取两个元素才能计算if(c!='!'){a= Sim_stack.Top();Sim_stack.Pop();b= Sim_stack.Top();Sim_stack.Pop();}
}//选择要计算的运算符
void Switch_Operator(char c)
{switch(c){case '~':Iif(); break;case '>':If(); break;case '|':Or(); break;case '&':And(); break;case '!':Not();break;}
}//进行!运算
void Not()
{a=Sim_stack.Top();Sim_stack.Pop();res= a==1?0:1;   //一定要注意是等于号Sim_stack.Push(res);
}//进行合取运算
void And()
{res=a*b;Sim_stack.Push(res);
}//进行析取运算
void Or()
{res= a+b==0?0:1;Sim_stack.Push(res);
}//进行条件运算
void If()
{res= (b==1&&a==0)?0:1;Sim_stack.Push(res);
}//进行双条件运算
void Iif()
{res= a==b?1:0;Sim_stack.Push(res);
}

离散数学之主析取范式,主合取范式相关推荐

  1. 【c++】[自动生成真值表/主析取范式/主合取范式的计算器]

    关于自动生成真值表/主析取范式/主合取范式的计算器 我用c++写了一个,需要的自取,如果好用请点赞 链接:https://pan.baidu.com/s/1Ji1zPDtjAc6-TDxovEzMVw ...

  2. 离散数学范式c语言实验报告,离散数学实验报告-利用真值表法求主析取范式及主合取范式的实现...

    1.实 验 报 告( / 学年 第 一 学期)课程名称离散数学实验名称利用真值表法求主析取范式及主合取范式的实现实验时间年月日指导单位指导教师学生姓名班级学号学院(系)专 业 实 验 报 告实验名称利 ...

  3. 【离散数学】Java语言实现利用真值表法求主析取范式和主合取范式

    C++版本的看这个链接: [离散数学]C++语言实现利用真值表法求主析取范式和主合取范式_zhtstar的博客-CSDN博客https://blog.csdn.net/weixin_56319483/ ...

  4. 【离散数学】C++语言实现利用真值表法求主析取范式和主合取范式

    Java版本的如下链接所示: Java语言实现利用真值表法求主析取范式和主合取范式_zhtstar的博客-CSDN博客https://blog.csdn.net/weixin_56319483/art ...

  5. 离散数学 求命题公式的主析取范式和主合取范式

    Description 输入命题公式的合式公式,求出公式的真值表,并输出该公式的主合取范式和主析取范式. Input 命题公式的合式公式 Output 公式的主析取范式和主合取范式,输出形式为:&qu ...

  6. 大二(上)离散数学 主析取范式与主合取范式

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> ...

  7. 离散数学实践一编程判断主析取范式和主合取范式【java实现】

    文章目录 实验要求 二 编程思路分析 困难所在 二 完整代码 实验要求 实验类型:设计性 实验目的 通过算法设计并编程实现,使学生掌握利用计算机语言判别合式公式主范式的基本方法. 实验内容 给定合式公 ...

  8. 离散实验 真值表求主析取范式、主合取范式的计算机语言实现

    离散数学 实验一 标题:真值表求主析取范式.主合取范式的计算机语言实现 其他课程的一些其他实验源码也可在本人github主页找到哦 链接如下:https://github.com/Schiz0mani ...

  9. 使用C++求命题公式的主析取范式与主合取范式

    最近的离散数学的一个上机作业,要求任意输入一个命题公式,求它的真值表与主析取范式和主合取范式.其中的命题连接词都是用特殊符号来表示(怕麻烦--),并最终选择使用C++来编写程序. 先贴代码: // 五 ...

  10. 求主析取范式与主合取范式

    定义设A为恰含命题变元p1,-,pn的公式.公式A称为A的主析(合)取范式(majordisjunctive(conjunctive)normal form),如果A是A的析(合)取范式,并且其每个合 ...

最新文章

  1. 富士康裁员六万,试图用机器人扭转赤字?
  2. Flomaster 2020中文版
  3. Linux服务器的最大内存和CPU数
  4. if,elif,else的关系 input print int的用法
  5. Python入门100题 | 第079题
  6. 深度阅读之《Mastering Go》
  7. 前端学习(2966):上午回顾
  8. Linux 普通用户和超级用户的切换
  9. 字节跳动面试:java后端面试宝典
  10. 基于Java+SpringBoot+vue+node.js的智能农场管理系统详细设计和实现
  11. 2020互联网行业术语
  12. win10计算机不显示usb,win10系统U盘不识别怎么办 没有显示U盘的解决方法
  13. java绘制雷达图_【带着canvas去流浪(6)】绘制雷达图
  14. Research Mindmap
  15. 不可错过的《一步一步学Spring Boot》视频教程
  16. 5.3.3—二叉查找树—Validate Binary Sear Tree
  17. 全栈式PHP集成环境-laragon(二) 配置、使用
  18. python手机号码标记_python 判断号码是否可用(号码过滤)
  19. 腾讯云部署Flask应用
  20. 如何检查DirectX的版本(用于Windows Phone Developer Tools的安装检查)

热门文章

  1. C++ 中 ifstream读取txt文件内容
  2. 2021-08-08 WPF控件专题 StackPanel 控件详解
  3. 2017c语言国二试题,国家计算机c语言二级考试试题
  4. mysql创建学生表命令_用sql语句创建学生表如何做
  5. 【 地图系列 】 中国各省市县级 JSON 文件
  6. html里的音频插件,html5音频播放插件
  7. 瑞友天翼 v5.1.0.6 远程打印跳行、跳页、错位问题解决方法
  8. Day11 JaseSE File类的使用
  9. excel计算机二级考试试题,计算机二级考试Excel操作考试题.doc
  10. SQLPrompt关闭联网