给出相应主析取和主合取范式

发布时间:2025-06-24 17:50:54  作者:北方职教升学中心  阅读量:068


//! //联结词改造函数char*conjuction(chara[],size_tlen)//len表示字符串长度{for(inti =0;i <len;i++){if(a[i]=='!')a[i]='6';elseif(a[i]=='&')a[i]='2';elseif(a[i]=='|')a[i]='3';elseif(a[i]=='>')a[i]='4';elseif(a[i]=='-')a[i]='5';}returna;}

联结词计算函数

对每个联结词对应的计算方法写成函数。

  • 主合取范式:真值结果为假F,变元如果为真就写为否定 !P,如果为假就不取否定。

    //改PQ值为1 0voidchange(chara[],size_tlen,charb1,charb2,charb3){for(intj =0;j <len;j++){if(a[j]=='P')a[j]=b1;elseif(a[j]=='Q')a[j]=b2;elseif(a[j]=='R')a[j]=b3;}}

    命题变元个数判断函数

    直接循环遍历然后记录出现次数就行。

//单变元打印voidonePrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("Pt%sn",a);charb[MAX];conjuction(a,len);charret;strcpy(b,a);ret =count(a,len,'1','1','1');printf("1t%cn",ret);strcpy(a,b);ret =count(a,len,'0','0','0');printf("0t%cn",ret);}//双变元打印voidtwoPrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("PtQt%sn",a);charb[MAX];charret;conjuction(a,len);strcpy(b,a);ret =count(a,len,'1','1','0');//存储范式值if(ret =='0')strcat(pri,"(!P|!Q)&");elseif(ret =='1')strcat(dis,"(P&Q)|");printf("1t1t%cn",ret);strcpy(a,b);ret =count(a,len,'1','0','0');//存储范式值if(ret =='0')strcat(pri,"(!P|Q)&");elseif(ret =='1')strcat(dis,"(P&!Q)|");printf("1t0t%cn",ret );strcpy(a,b);ret =count(a,len,'0','1','0');//存储范式值if(ret =='0')strcat(pri,"(P|!Q)&");elseif(ret =='1')strcat(dis,"(!P&Q)|");printf("0t1t%cn",ret);strcpy(a,b);ret =count(a,len,'0','0','0');//存储范式值if(ret =='0')strcat(pri,"(P|Q)&");elseif(ret =='1')strcat(dis,"(!P&!Q)|");printf("0t0t%cn",ret );}//三变元打印voidthreePrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("PtQtRt%sn",a);charb[MAX];charret;conjuction(a,len);strcpy(b,a);ret =count(a,len,'1','1','1');//计算范式if(ret =='1')strcat(dis,"(P&Q&R)|");elseif(ret =='0')strcat(pri,"(!P|!Q|!R)&");printf("1t1t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'1','1','0');if(ret =='1')strcat(dis,"(P&Q&!R)|");elseif(ret =='0')strcat(pri,"(!P|!Q|R)&");printf("1t1t0t%cn",ret );strcpy(a,b);//计算范式ret =count(a,len,'1','0','1');if(ret =='1')strcat(dis,"(P&!Q&R)|");elseif(ret =='0')strcat(pri,"(!P|Q|!R)&");printf("1t0t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'1','0','0');if(ret =='1')strcat(dis,"(P&!Q&!R)|");elseif(ret =='0')strcat(pri,"(!P|Q|R)&");printf("1t0t0t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','1','1');if(ret =='1')strcat(dis,"(!P&Q&R)|");elseif(ret =='0')strcat(pri,"(P|!Q|!R)&");printf("0t1t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','1','0');if(ret =='1')strcat(dis,"(!P&Q&!R)|");elseif(ret =='0')strcat(pri,"(P|!Q|R)&");printf("0t1t0t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','0','1');if(ret =='1')strcat(dis,"(!P&!Q&R)|");elseif(ret =='0')strcat(pri,"(P|Q|!R)&");printf("0t0t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','0','0');if(ret =='1')strcat(dis,"(!P&!Q&!R)|");elseif(ret =='0')strcat(pri,"(P|Q|R)&");printf("0t0t0t%cn",ret);}//主析取范式打印voiddisPrint(chardis[],size_tdisLen){printf("该合式公式的主析取范式:n");for(inti =1;i <disLen -1;i++)printf("%c",dis[i]);printf("n");}//主合取范式打印voidpriPrint(charpri[],size_tpriLen){printf("该合式公式的主合取范式:n");for(inti =1;i <priLen -1;i++)printf("%c",pri[i]);printf("n");}

主函数中调用

调用思路如下:

  • 主函数中用一个字符数组来接收传来的合式公式。

    实验要求

    要求:

    • 从屏幕输入含三个以内变量的合式公式(其中 联结词按照从高到底的顺序出现)。

  • 给出相应主析取和主合取范式。

    //计算函数charcount(chara[],size_tlen,charb1,charb2,charb3){change(a,len,b1,b2,b3);for(intj =0;j <len;j++){if(a[j]>='2'){inttem =(int)a[j]-48;switch(tem){case2:a[j +1]=and1(a[j -1],a[j +1]);break;case3:a[j +1]=or1(a[j -1],a[j +1]);break;case4:a[j +1]=con(a[j -1],a[j +1]);break;case5:a[j +1]=dou_con(a[j -1],a[j +1]);break;case6:a[j +1]=dif(a[j +1]);break;default:break;}}}returna[len -1];}

    改命题变元值

    将命题变元传来是真假分别用1 0来表示,但我写的代码只能将命题变元用PQR表示,其他不行。

  • 然后再根据命题变元个数调用对应的打印函数。

    //|计算函数charor1(chara,charb){if(a =='0'&&b =='0')return'0';return'1';}//&计算函数charand1(chara,charb){if(a =='1'&&b =='1')return'1';return'0';}//!计算函数chardif(chara){if(a =='0')return'1';return'0';}//条件判断函数charcon(chara,charb){if(a =='1'&&b =='0')return'0';elsereturn'1';}//双条件判断函数chardou_con(chara,charb){if(a ==b)return'1';elsereturn'0';}

    总计算方法

    我们还需要写一个函数将联结词计算方法串起来,并对合式公式进行计算。

    //判断命题变元数量函数intjudgeNum(chara[],size_tlen){intnumP =0;intnumQ =0;intnumR =0;intnum =0;for(inti =0;i <len;i++){if(a[i]=='P')numP++;elseif(a[i]=='Q')numQ++;elseif(a[i]=='R')numR++;}if(numP >0)num++;if(numQ >0)num++;if(numR >0)num++;returnnum;}

    打印函数

    在写打印函数之前我们先来回顾一下如何根据真值表得出范式。
    我们就设计一个函数将这些联结词改造对应的数字,以便后面switch case操作(可以省略直接在case中判断符号就行)。

  • 在调用命题变元判断函数来判断有几个命题变元。

    用switch case来进行计算。

  • 主析取范式:真值结果为真T,变元如果为假就写为否定!P,如果为真就不取否定。

    目录

    • 实验
      • 实验内容
      • 实验要求
    • 具体实现
      • 改造联结词
      • 联结词计算函数
      • 总计算方法
      • 改命题变元值
      • 命题变元个数判断函数
      • 打印函数
      • 主函数中调用
    • 源码

    在这里插入图片描述
    在这里插入图片描述

    实验

    实验内容

    编程实现用真值表法求取含三个以内变量的合式公式的主析取范式和主合取范式。

  • 规范列出所输合式公式的真值表。
    [外链图片转存中…(img-KttFRYgu-1719842214597)]

  • 具体实现

    具体实现可以参考以下思路:

    改造联结词

    在输入联结词时就会要求用!表示否定,&表示合取,|表示析取,>表示条件,-表示双条件。

    intmain(){printf("输入不超过三种命题变元(PQR表示)的合式公式(联结词优先级从高到低):\n");chara[MAX];chardisNorForm[MAXX]="0";//主析取范式charpriConNorForm[MAXX]="0";//主合取范式scanf("%s",a);size_tlen =strlen(a);size_tdisLen;size_tpriLen;intnum =judgeNum(a,len);switch(num){case1:onePrint(a,len,disNorForm,priConNorForm);printf("该合式公式无主合取范式和主析取范式");break;case2:twoPrint(a,len,disNorForm,priConNorForm);disLen =strlen(disNorForm);disPrint(disNorForm,disLen);priLen =strlen(priConNorForm);priPrint(priConNorForm,priLen);break;case3:threePrint(a,len,disNorForm,priConNorForm);disLen =strlen(disNorForm);disPrint(disNorForm,disLen);priLen =strlen(priConNorForm);priPrint(priConNorForm,priLen);break;default:break;}return0;}

    源码

    源码呈上:

    #include<stdio.h>#include<string.h>#defineMAX20#defineMAXX40//联结词改造函数char*conjuction(chara[],size_tlen);//|计算函数charor1(chara,charb);//&计算函数charand1(chara,charb);//!计算函数chardif(chara);//条件判断函数charcon(chara,charb);//双条件判断函数chardou_con(chara,charb);//改PQ值为1 0voidchange(chara[],size_tlen,charb1,charb2,charb3);//计算函数charcount(chara[],size_tlen,charb1,charb2,charb3);//判断命题变元数量函数intjudgeNum(chara[],size_tlen);//单变元打印voidonePrint(chara[],size_tlen,chardis[],charpri[]);//双变元打印voidtwoPrint(chara[],size_tlen,chardis[],charpri[]);//三变元打印voidthreePrint(chara[],size_tlen,chardis[],charpri[]);//主合取范式打印voidpriPrint(charpri[],size_tpriLen);//主析取范式打印voiddisPrint(chardis[],size_tdisLen);intmain(){printf("输入不超过三种命题变元(PQR表示)的合式公式(联结词优先级从高到低):\n");chara[MAX];chardisNorForm[MAXX]="0";//主析取范式charpriConNorForm[MAXX]="0";//主合取范式scanf("%s",a);size_tlen =strlen(a);size_tdisLen;size_tpriLen;intnum =judgeNum(a,len);switch(num){case1:onePrint(a,len,disNorForm,priConNorForm);printf("该合式公式无主合取范式和主析取范式");break;case2:twoPrint(a,len,disNorForm,priConNorForm);disLen =strlen(disNorForm);disPrint(disNorForm,disLen);priLen =strlen(priConNorForm);priPrint(priConNorForm,priLen);break;case3:threePrint(a,len,disNorForm,priConNorForm);disLen =strlen(disNorForm);disPrint(disNorForm,disLen);priLen =strlen(priConNorForm);priPrint(priConNorForm,priLen);break;default:break;}return0;}//! //联结词改造函数char*conjuction(chara[],size_tlen){for(inti =0;i <len;i++){if(a[i]=='!')a[i]='6';elseif(a[i]=='&')a[i]='2';elseif(a[i]=='|')a[i]='3';elseif(a[i]=='>')a[i]='4';elseif(a[i]=='-')a[i]='5';}returna;}//|计算函数charor1(chara,charb){if(a =='0'&&b =='0')return'0';return'1';}//&计算函数charand1(chara,charb){if(a =='1'&&b =='1')return'1';return'0';}//!计算函数chardif(chara){if(a =='0')return'1';return'0';}//条件判断函数charcon(chara,charb){if(a =='1'&&b =='0')return'0';elsereturn'1';}//双条件判断函数chardou_con(chara,charb){if(a ==b)return'1';elsereturn'0';}//改PQR值为1 0voidchange(chara[],size_tlen,charb1,charb2,charb3){for(intj =0;j <len;j++){if(a[j]=='P')a[j]=b1;elseif(a[j]=='Q')a[j]=b2;elseif(a[j]=='R')a[j]=b3;}}//计算函数charcount(chara[],size_tlen,charb1,charb2,charb3){change(a,len,b1,b2,b3);for(intj =0;j <len;j++){if(a[j]>='2'){inttem =(int)a[j]-48;switch(tem){case2:a[j +1]=and1(a[j -1],a[j +1]);break;case3:a[j +1]=or1(a[j -1],a[j +1]);break;case4:a[j +1]=con(a[j -1],a[j +1]);break;case5:a[j +1]=dou_con(a[j -1],a[j +1]);break;case6:a[j +1]=dif(a[j +1]);break;default:break;}}}returna[len -1];}//判断命题变元数量函数intjudgeNum(chara[],size_tlen){intnumP =0;intnumQ =0;intnumR =0;intnum =0;for(inti =0;i <len;i++){if(a[i]=='P')numP++;elseif(a[i]=='Q')numQ++;elseif(a[i]=='R')numR++;}if(numP >0)num++;if(numQ >0)num++;if(numR >0)num++;returnnum;}//单变元打印voidonePrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("Pt%sn",a);charb[MAX];conjuction(a,len);charret;strcpy(b,a);ret =count(a,len,'1','1','1');printf("1t%cn",ret);strcpy(a,b);ret =count(a,len,'0','0','0');printf("0t%cn",ret);}//双变元打印voidtwoPrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("PtQt%sn",a);charb[MAX];charret;conjuction(a,len);strcpy(b,a);ret =count(a,len,'1','1','0');//存储范式值if(ret =='0')strcat(pri,"(!P|!Q)&");elseif(ret =='1')strcat(dis,"(P&Q)|");printf("1t1t%cn",ret);strcpy(a,b);ret =count(a,len,'1','0','0');//存储范式值if(ret =='0')strcat(pri,"(!P|Q)&");elseif(ret =='1')strcat(dis,"(P&!Q)|");printf("1t0t%cn",ret );strcpy(a,b);ret =count(a,len,'0','1','0');//存储范式值if(ret =='0')strcat(pri,"(P|!Q)&");elseif(ret =='1')strcat(dis,"(!P&Q)|");printf("0t1t%cn",ret);strcpy(a,b);ret =count(a,len,'0','0','0');//存储范式值if(ret =='0')strcat(pri,"(P|Q)&");elseif(ret =='1')strcat(dis,"(!P&!Q)|");printf("0t0t%cn",ret );}//三变元打印voidthreePrint(chara[],size_tlen,chardis[],charpri[]){printf("该合式公式真值表如下表示:n");printf("PtQtRt%sn",a);charb[MAX];charret;conjuction(a,len);strcpy(b,a);ret =count(a,len,'1','1','1');//计算范式if(ret =='1')strcat(dis,"(P&Q&R)|");elseif(ret =='0')strcat(pri,"(!P|!Q|!R)&");printf("1t1t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'1','1','0');if(ret =='1')strcat(dis,"(P&Q&!R)|");elseif(ret =='0')strcat(pri,"(!P|!Q|R)&");printf("1t1t0t%cn",ret );strcpy(a,b);//计算范式ret =count(a,len,'1','0','1');if(ret =='1')strcat(dis,"(P&!Q&R)|");elseif(ret =='0')strcat(pri,"(!P|Q|!R)&");printf("1t0t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'1','0','0');if(ret =='1')strcat(dis,"(P&!Q&!R)|");elseif(ret =='0')strcat(pri,"(!P|Q|R)&");printf("1t0t0t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','1','1');if(ret =='1')strcat(dis,"(!P&Q&R)|");elseif(ret =='0')strcat(pri,"(P|!Q|!R)&");printf("0t1t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','1','0');if(ret =='1')strcat(dis,"(!P&Q&!R)|");elseif(ret =='0')strcat(pri,"(P|!Q|R)&");printf("0t1t0t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','0','1');if(ret =='1')strcat(dis,"(!P&!Q&R)|");elseif(ret =='0')strcat(pri,"(P|Q|!R)&");printf("0t0t1t%cn",ret);strcpy(a,b);//计算范式ret =count(a,len,'0','0','0');if(ret =='1')strcat(dis,"(!P&!Q&!R)|");elseif(ret =='0')strcat(pri,"(P|Q|R)&");printf("0t0t0t%cn",ret);}//主析取范式打印voiddisPrint(chardis[],size_tdisLen){printf("该合式公式的主析取范式:n");for(inti =1;i <disLen -1;i++)printf("%c",dis[i]);printf("n");}//主合取范式打印voidpriPrint(charpri[],size_tpriLen){printf("该合式公式的主合取范式:n");for(inti =1;i <priLen -1;i++)printf("%c",pri[i]);printf("n");}

    写的可能有点冗杂屎山读者见谅。