離散數學輸入表示式列印真值表和主析/合取正規化
阿新 • • 發佈:2019-01-02
這是我們學校離散數學的作業題目,我用JAVA寫的,不廢話,上程式碼:
package lisanExperiment; import java.io.BufferedReader; import java.io.InputStreamReader; public class li { //使用者輸入的表示式(以字串形式輸入) StringBuilder inputStr; //用於作為inputStr的副本,當每次計算完成後重置inputStr String inputStr2; //flag代表表示式的結果 int flag=0; //用於統計最初輸入的表示式有幾個括號 int count=0; //用於控制遞迴次數 int COUNT; //下面的陣列用於儲存真值表 int [][]table=new int[8][4]; //用於表示是否含有括號 boolean ifHas=false; //用於存放P,Q,R String[]pqr=new String[]{"P","Q","R"}; //用於讓使用者輸入字串的函式 public void input(StringBuilder string) { inputStr=string; inputStr2=string.toString(); } //每輪迴圈之後重置 public void restart() { inputStr=new StringBuilder(inputStr2); } //用於處理"!"運算子 public int changeI(int x) { if(x==0) return 1; return 0; } public String changeS(int x) { if(x==0) return "1"; return "0"; } //用於處理析取運算子 public int extract(int x,int y) { return (x|y); } //用於處理合取運算子 public int conjunct(int x,int y) { return (x&y); } //運算不同情況下的表示式值,x是P的值,y的Q的值,z是R的值 public void Calculate(int x,int y,int z) { // System.out.println("FIRST\t"+inputStr); if(count==0&&ifHas==false) { for(int i=0;i<inputStr.length();i++) { if(inputStr.charAt(i)==')') { count++; ifHas=true; } COUNT=count; } } //System.out.println("COUNT"+COUNT); if(COUNT!=0) { COUNT--; for(int i=0;i<inputStr.length();i++) { if(inputStr.charAt(i)==')') { for(int j=i;;j--) { if(inputStr.charAt(j)=='(') { int result; String[]strs=new String[3]; strs[0]=inputStr.substring(0,j); strs[1]=inputStr.substring(j+1,i); strs[2]=inputStr.substring(i+1); StringBuilder s=new StringBuilder(strs[1]); result=computeSim(s,x,y,z); String string=strs[0]+result+strs[2]; inputStr= new StringBuilder(string); //System.out.println("LAST\t"+inputStr); break; } } break; } } if(COUNT!=0) { Calculate(x,y,z); } if(COUNT==0) { //System.out.println("我被呼叫了"); flag=computeSim(inputStr,x,y,z); } } } //用於計算最內側括號裡的值 public int computeSim(StringBuilder sb,int x,int y,int z) { //這是已經計算的部分的真值 int been=0; for(int i=0;i<sb.length();i++) { if(sb.charAt(i)=='!') { if(sb.charAt(i+1)=='P') sb.replace(i, i+2, changeS(x)); else if(sb.charAt(i+1)=='Q') sb.replace(i, i+2, changeS(y)); else if(sb.charAt(i+1)=='R') sb.replace(i, i+2, changeS(z)); else if(sb.charAt(i+1)=='1') sb.replace(i, i+2, "0"); else if(sb.charAt(i+1)=='0') sb.replace(i, i+2, "1"); //System.out.println("刪除了一個非"); } } for(int i=0;i<sb.length();i++) { //以下程式碼用於初始化been if(i==0) { if(sb.charAt(i)=='P') been=x; else if(sb.charAt(i)=='Q') been=y; else if(sb.charAt(i)=='R') been=z; else if(sb.charAt(i)=='1') been=1; else if(sb.charAt(i)=='0') been=0; } switch(sb.charAt(i)) { case'!': break; case '|': if(sb.charAt(i+1)=='P') been=extract(been,x); if(sb.charAt(i+1)=='Q') been=extract(been,y); if(sb.charAt(i+1)=='R') been=extract(been,z); if(sb.charAt(i+1)=='1') been=extract(been,1); if(sb.charAt(i+1)=='0') been=extract(been,0); break; case '&': if(sb.charAt(i+1)=='P') been=conjunct(been,x); if(sb.charAt(i+1)=='Q') been=conjunct(been,y); if(sb.charAt(i+1)=='R') been=conjunct(been,z); if(sb.charAt(i+1)=='0') been=conjunct(been,0); if(sb.charAt(i+1)=='1') been=conjunct(been,1); break; default: break; } } return been; } public void init() { int n=0; for(int i=1;i>=0;i--) { for(int j=1;j>=0;j--) { for(int k=1;k>=0;k--) { Calculate(i,j,k); table[n][0]=i; table[n][1]=j; table[n][2]=k; table[n][3]=flag; n++; restart(); COUNT=count; // System.out.println(inputStr); } } } } //用於把1和0轉換為T和F public String replace(int x) { if(x==1) return "T"; return "F"; } public void print() { System.out.println("P\tQ\tR\t"+inputStr); for(int i=0;i<8;i++) { for(int j=0;j<4;j++) System.out.print(replace(table[i][j])+"\t"); System.out.println(); } } public void mainX() { int x=0; for(int i=0;i<8;i++) if(table[i][3]==1) x=i; System.out.println("該式的主析取正規化"); for(int i=0;i<8;i++) { if(table[i][3]==1) { System.out.print("("); for(int j=0;j<3;j++) { if(table[i][j]==0) System.out.print("!"+pqr[j]); else System.out.print(pqr[j]); if(j!=2) System.out.print("&"); else System.out.print(")"); } if(i!=x) System.out.print("|"); } } System.out.println(); } public void mainH() { int x=0; for(int i=0;i<8;i++) if(table[i][3]==0) x=i; System.out.println("該式的主合取正規化"); for(int i=0;i<8;i++) { if(table[i][3]==0) { System.out.print("("); for(int j=0;j<3;j++) { if(table[i][j]==1) System.out.print("!"+pqr[j]); else System.out.print(pqr[j]); if(j!=2) System.out.print("|"); else System.out.print(")"); } if(i!=x) System.out.print("&"); } } System.out.println(); } public static void main(String []args)throws Exception { li l=new li(); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); System.out.println("請輸入表示式,三個命題分別為P,Q,R,非號用!代替,析取號用|代替,合取號用&代替"); System.out.println("輸入不當可能導致未知錯誤,請注意輸入格式"); String s=null; s=br.readLine(); StringBuilder sb=new StringBuilder(s); l.input(sb); l.init(); l.print(); l.mainX(); l.mainH(); } }
事後感覺自己寫的蠢了,另外要完成不確定個數的變元輸入並不困難,甚至比確定的三個還要簡單。
水平有限,敬請指教。