离散数学编程输出主析取范式(二进制排列转十进制输出)
【問(wèn)題描述】
請(qǐng)根據(jù)給定的命題公式,計(jì)算其真值為T的小項(xiàng),列出主析取范式,并輸出結(jié)果。
【輸入形式】
輸入一個(gè)字符串(字符串長(zhǎng)度<=50)形式的命題公式,以回車表示輸入結(jié)束。其中的命題公式為僅包含原子命題、聯(lián)結(jié)詞和括號(hào)的合式公式。聯(lián)結(jié)詞僅包含下述5中聯(lián)結(jié)詞:
1、否定,表示為“!”
2、合取,表示為“*”
3、析取,表示為“|”
4、條件,表示為“-”
5、雙條件,表示為“=”
例如:
(P-Q)-R
注意:輸入符號(hào)均采用英文輸入。
【輸出形式】
輸出一個(gè)以單個(gè)空格分隔的字符串,字符串中各項(xiàng)分別對(duì)應(yīng)主析取范式中小項(xiàng)的序號(hào)。
如(P-Q)- R對(duì)應(yīng)的小項(xiàng)為Σ1,3,4,5,7
則輸出1 3 4 5 7
注意:其中的原子命題按字母表排序。
【樣例輸入】
(P-Q)- R
【樣例輸出】
1 3 4 5 7
代碼小白的我拿到題目毫無(wú)頭緒,參考了其他人的代碼(都是直接輸出真值表和主析取主合取范式),最后改了一份在我理解范圍內(nèi)的代碼【鏈接會(huì)放文末(侵刪)】,但是代碼依然有問(wèn)題,輸出有些對(duì)有些不對(duì),想了兩天想不出來(lái)問(wèn)題在哪,先存下現(xiàn)在的代碼,以后二改【菜得安詳.jpg】
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> using namespace std;//將命題公式中的命題變?cè)鎯?chǔ)到數(shù)組b中 ,并對(duì)b中字母排序 int SearchAlpha(char* a,char* b){int lena=strlen(a);int endposition=0,flag=0;//選出命題公式中的命題變?cè)?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中字母不重復(fù) }if(flag==0){b[endposition]=a[i]; endposition++;}}} b[endposition]='\0'; char temp=1;//對(duì)數(shù)組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;//化簡(jiǎn)否定!,優(yōu)先級(jí)最高 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];//所有的都向前面挪動(dòng)一個(gè)單位,包括'\0' j++;}a[j]='\0';}else point++; } //化簡(jiǎn)合取*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++;} //化簡(jiǎn)() 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++;}//化簡(jiǎn)雙條件= 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++;} //化簡(jiǎn)單條件 - 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++;} //化簡(jiǎn)析取|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]即為對(duì)應(yīng)真值分配情況下的命題公式的真值 // 按行打印真值表,times代表行數(shù),truetable為每行真值表 ,a1存儲(chǔ)對(duì)應(yīng)真值表的命題公式真值 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;//將命題公式復(fù)制到數(shù)組 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對(duì)應(yīng)真值表中的行數(shù) while(temptimes>0){truetable[position]=temptimes%2;position++;temptimes/=2;} int temp=0,exlimit=0;int realtable[lenalpha];//起中間量作用的數(shù)組 for(int i=0;i<lenalpha;i++){realtable[i]=truetable[lenalpha-i-1];//逆向打印真值表 (每行) } for(int i=0;i<lenalpha;i++){truetable[i]=realtable[i];}//開(kāi)始對(duì)其中的字母與標(biāo)準(zhǔn)字母進(jìn)行比對(duì)并分配真值 //將真值賦給命題變?cè)?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
總結(jié)
以上是生活随笔為你收集整理的离散数学编程输出主析取范式(二进制排列转十进制输出)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++ _countf
- 下一篇: Ural 1519. Formula 1