离散数学之主析取范式、主合取范式:离散数学上机实验,给定一个命题公式,求其主析取范式,主合取范式,能力有限,参考了我学长的一篇博客,并进行了许多优化。
本次离散数学实验,我学到了许多东西,也看了自己的不足之处
1).我深刻地体会到在比较大型的软件的开发过程中预先进行设计的重要性,就拿这个小程序来说,
如果不预先设计好程序需要的算法,各个函数,解决方法的一步步流程,那么在真正开发过程中效率将大大降低,会不断地删除修改,有时候甚至要重写,这都是事先没有进行计划的原因。
2).程序设计中算法的重要性,本程序用到了将命题公式转化为逆波兰表达式的算法,我起先一点也不会,但是看了学长的源代码理解了个大概,自己又仔细琢磨琢磨,也就写出来了,但是现在让我独立再写一遍我是真的 写不出来了
3).大型程序中函数名称的规范性,起先我嫌弃命名规范的话敲起代码来很不舒服,可是随着程序越来越大,程序变得越来越难读,最终我全部换成了能一眼看出功能函数名
4).要学会版本控制系统
各个版本原代码:各个版本代码
#include#include #include #include 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)//如果栈溢出,返回false return 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_stack int 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^*//"< ******************"< " ;i+="2;" }="" else="" ;="" 重要,给字符串加上结束标记符="" original_formula="str1;" simp_formula="str2;" *************************输入并且进行简化************************************************="" *************************增强程序鲁棒性**************************************************="" bool="" enh_robustness()="" rob="true;" if(original_formula="="Over")" return="" true;="" for(int="" i="0;i ':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 =0;p--) { for(q=1;q>=0;q--) { Calculate(); if(res==1) PDNF=PDNF+"("+(p==1?"P":"┐P")+"∧"+(q==1?"Q":"┐Q")+")"+"∨"; else PCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+")"+"∧"; cout<<><><> =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")+")"+"∨"; else PCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+")"+"∧"; cout<<><><><> =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")+")"+"∨"; else PCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+"∨"+(s==0?"R":"┐R")+")"+"∧"; cout<<><><><><> =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")+")"+"∨"; else PCNF=PCNF+"("+(p==0?"P":"┐P")+"∨"+(q==0?"Q":"┐Q")+"∨"+(r==0?"R":"┐R")+"∨"+(s==0?"R":"┐R")+")"+"∧"; cout<<><><><><><> ':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); } <><><><><> <><><><> <><><> <><>