离散数学编程输出主析取范式(二进制排列转十进制输出)
生活随笔
收集整理的這篇文章主要介紹了
离散数学编程输出主析取范式(二进制排列转十进制输出)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【問題描述】
請根據給定的命題公式,計算其真值為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
總結
以上是生活随笔為你收集整理的离散数学编程输出主析取范式(二进制排列转十进制输出)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ _countf
- 下一篇: Ural 1519. Formula 1