【问题描述】 请根据给定的命题公式,计算其真值为T的小项,列出主析取范式,并输出结果。
【输入形式】 输入一个字符串(字符串长度<=50)形式的命题公式,以回车表示输入结束。其中的命题公式为仅包含原子命题、联结词和括号的合式公式。联结词仅包含下述5中联结词: 1、否定,表示为“!” 2、合取,表示为“*” 3、析取,表示为“|” 4、条件,表示为“-” 5、双条件,表示为“=” 例如: (P-Q)-R 注意:输入符号均采用英文输入。
【输出形式】 输出一个以单个空格分隔的字符串,字符串中各项分别对应主析取范式中小项的序号。 如(P-Q)- R对应的小项为Σ1,3,4,5,7 则输出1 3 4 5 7 注意:其中的原子命题按字母表排序。
【样例输入】 (P-Q)- R
【样例输出】 1 3 4 5 7
代码小白的我拿到题目毫无头绪,参考了其他人的代码(都是直接输出真值表和主析取主合取范式),最后改了一份在我理解范围内的代码【链接会放文末(侵删)】,但是代码依然有问题,输出有些对有些不对,想了两天想不出来问题在哪,先存下现在的代码,以后二改【菜得安详.jpg】
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> using namespace std; //将命题公式中的命题变元存储到数组b中 ,并对b中字母排序 int SearchAlpha(char* a,char* b){ int lena=strlen(a); int endposition=0,flag=0; //选出命题公式中的命题变元 for(int i=0;i<lena;i++){ if((a[i]>='a')&&(a[i]<='z')||(a[i]>='A')&&(a[i]<='Z')){ flag=0; for(int j=0;j<endposition;j++){ if(a[i]==b[j])flag=1;//保证b中字母不重复 } if(flag==0){ b[endposition]=a[i]; endposition++; } } } b[endposition]='\0'; char temp=1; //对数组b中字母排序 for(int i=0;i<endposition;i++){ for(int j=i+1;j<endposition;j++){ if(b[i]>b[j]){ temp=b[i];b[i]=b[j];b[j]=temp; } } } return endposition; } char trans(int b){ return b+'0'; } void simplify(char* a){ int point=0,j=point,pd=0; //化简否定!,优先级最高 while(point<strlen(a)){ j=point;pd=0; if(((j+1)<strlen(a))&&(a[j]=='!')&&(a[j+1]=='1')){ a[j]='0';pd=1; } else if(((j+1)<strlen(a))&&(a[j]=='!')&&(a[j+1]=='0')){ a[j]='1';pd=1; } if(pd==1){ j++; while(a[j+1]!='\0'){ a[j]=a[j+1];//所有的都向前面挪动一个单位,包括'\0' j++; } a[j]='\0'; } else point++; } //化简合取* point=j=0,pd=0; while(point<strlen(a)){ j=point;pd=0; if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='*')&&(a[j+2]=='0')){ a[j]='0';pd=1; } else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='*')&&(a[j+2]=='1')){ a[j]='0',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='*')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='*')&&(a[j+2]=='0')){ a[j]='0',pd=1; } if(pd==1){ j++; while(a[j+2]!='\0'){ a[j]=a[j+2];//前移两位 j++; } a[j]='\0'; } else point++; } //化简() point=j=0,pd=0; while(point<strlen(a)){ j=point;pd=0; if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='1')&&(a[j+2]==')')){ a[j]='1';pd=1; } else if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='0')&&(a[j+2]==')')){ a[j]='0',pd=1; } if(pd==1){ j++; while(a[j+2]!='\0'){ a[j]=a[j+2];//前移两位 j++; } a[j]='\0'; } else point++; } //化简双条件= point=j=0,pd=0; while(point<strlen(a)){ j=point;pd=0; if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='0')){ a[j]='1';pd=1; } else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='1')){ a[j]='0',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='0')){ a[j]='0',pd=1; } if(pd==1){ j++; while(a[j+2]!='\0'){ a[j]=a[j+2];//前移两位 j++; } a[j]='\0'; } else point++; } //化简单条件 - point=j=0,pd=0; while(point<strlen(a)){ j=point;pd=0; if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='-')&&(a[j+2]=='0')){ a[j]='1';pd=1; } else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='-')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='-')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='-')&&(a[j+2]=='0')){ a[j]='0',pd=1; } if(pd==1){ j++; while(a[j+2]!='\0'){ a[j]=a[j+2];//前移两位 j++; } a[j]='\0'; } else point++; } //化简析取| point=j=0,pd=0; while(point<strlen(a)){ j=point;pd=0; if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='0')){ a[j]='0';pd=1; } else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='1')){ a[j]='1',pd=1; } else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='0')){ a[j]='1',pd=1; } if(pd==1){ j++; while(a[j+2]!='\0'){ a[j]=a[j+2];//前移两位 j++; } a[j]='\0'; } else point++; } } //a[0]即为对应真值分配情况下的命题公式的真值 // 按行打印真值表,times代表行数,truetable为每行真值表 ,a1存储对应真值表的命题公式真值 int Print_Truetable(char* a,char* b,char* a1,int* truetable,int times){ memset(truetable,0,sizeof(truetable)); int lena=strlen(a); int k=0; //将命题公式复制到数组 a1中 for(k=0;k<lena;k++){ a1[k]=a[k]; } a1[k]='\0'; int lenalpha=strlen(b); int position=0; int temptimes=times;//times对应真值表中的行数 while(temptimes>0){ truetable[position]=temptimes%2; position++; temptimes/=2; } int temp=0,exlimit=0; int realtable[lenalpha];//起中间量作用的数组 for(int i=0;i<lenalpha;i++){ realtable[i]=truetable[lenalpha-i-1]; //逆向打印真值表 (每行) } for(int i=0;i<lenalpha;i++){ truetable[i]=realtable[i]; } //开始对其中的字母与标准字母进行比对并分配真值 //将真值赋给命题变元 for(int i=0;i<lena;i++){ for(int j=0;j<lenalpha;j++){ if(a1[i]==b[j]){ a1[i]=trans(truetable[j]); } } } int formerlen=strlen(a1); simplify(a1); int latterlen=strlen(a1); if(formerlen!=latterlen){ while(formerlen!=strlen(a1)){ formerlen=strlen(a1); simplify(a1); latterlen=strlen(a1); } } if(a1[0]=='1')cout<<times<<" "; } int main(){ char a[50],b[50]; cin>>a; int lenalpha=SearchAlpha(a,b); int truetable[lenalpha]; char a1[lenalpha+1]; int times=0,maxn=pow(2,lenalpha); while(times<maxn){ for(int i=0;i<lenalpha;i++){ truetable[i]=0; } Print_Truetable(a,b,a1,truetable,times); times++; } return 0; }参考链接:https://blog.csdn.net/chenhanxuan1999/article/details/79841205