1. 程式人生 > 其它 >求解某個命題公式的真值表和主析取正規化和主合取正規化

求解某個命題公式的真值表和主析取正規化和主合取正規化

一、求解公式

  思路:

  1、首先我們要處理這個公式怎麼能被計算機怎樣方便的計算,我們人類所熟悉的是中綴表示式,但是計算機需要的不是我們這種,計算起來十分麻煩,因此我們首先要把這個公式轉換成字尾表示式(也就是逆波蘭式)不會的同學可以去看看我那篇逆波蘭表示式。

  2、然後我們要考慮公式符號的處理,因為我們計算機是沒有->(蘊含符號) 和 <->(等價符號) 和 (取非符號的)所以我們要自定義符號,這裡我把蘊含符號變成了‘-’號,等價符號變成了‘+’號,取非符號變成了‘ ! ',這樣一來計算再次被化簡。

  3、我們計算逆波蘭表示式要用到棧結構,不瞭解得話可以去看看我的棧結構的文章啊。

  4、最後是統計主析取正規化和主合取正規化和真值表

  5、我們只需要遍歷當前元素的個數,然後分別跑n個迴圈,就可以得到他們的真值表和主析取正規化。。。。

二、程式碼實現

  1 #include <iostream>
  2 #include <queue>
  3 #include <vector>
  4 #include <cstring>
  5 #include <string>
  6 #include <map>
  7 #include <cmath>
  8 #include <algorithm>
  9
#include <set> 10 #include <stack> 11 #include <cstdio> 12 #include <climits> 13 #define PII pair<int,int> 14 #define rep(i,z,n) for(int i = z;i <= n; i++) 15 #define per(i,n,z) for(int i = n;i >= z; i--) 16 #define ll long long 17 #define db double 18 #define
vi vector<int> 19 #define debug(x) cerr << "!!!" << x << endl; 20 using namespace std; 21 inline ll read() 22 { 23 ll s,r; 24 r = 1; 25 s = 0; 26 char ch = getchar(); 27 while(ch < '0' || ch > '9'){ 28 if(ch == '-') 29 r = -1; 30 ch = getchar(); 31 } 32 while(ch >= '0' && ch <= '9'){ 33 s = (s << 1) + (s << 3) + (ch ^ 48); 34 ch = getchar(); 35 } 36 return s * r; 37 } 38 inline void write(ll x) 39 { 40 if(x < 0) putchar('-'),x = -x; 41 if(x > 9) write(x / 10); 42 putchar(x % 10 + '0'); 43 } 44 //字尾表示式 45 string expression; 46 int cop(char c) 47 { 48 if(c == '+')//對應等價 49 return 1; 50 else if(c == '-')//對應蘊含 51 return 2; 52 else if(c == '|')//對應吸取 53 return 3; 54 else if(c == '&')//對應合取 55 return 4; 56 else if(c == '!')//對應取非 57 return 5; 58 return 0; 59 } 60 int prio(char c) 61 { 62 if(c == '(')//對應闊號 63 return 0; 64 else if(c == '+')//對應等價 65 return 1; 66 else if(c == '-')//對應蘊含 67 return 2; 68 else if(c == '|')//對應吸取 69 return 3; 70 else if(c == '&')//對應合取 71 return 4; 72 else if(c == '!')//對應取非 73 return 5; 74 return 0; 75 } 76 void aftExpression(string ms) 77 { 78 stack <char> ct;//定義一個ct容器儲存運算子 79 for(auto iter = ms.begin();iter != ms.end();iter++){ 80 if(*iter >= 'a' && *iter <= 'z')//如果是數字,直接入棧 81 expression += *iter; 82 else{ 83 if(ct.empty() || *iter == '(')//如果是空棧,或者是左括號,直接入棧 84 ct.push(*iter); 85 else if(*iter == ')'){ 86 while(ct.top() != '('){//把左括號和右括號裡面的操作符出棧 87 expression += ct.top(); 88 ct.pop(); 89 } 90 ct.pop();//彈出左括號 91 } 92 else{ 93 while(!ct.empty() && prio(*iter) <= prio(ct.top())){//把優先順序低於當前操作符的操作符出棧 94 expression += ct.top(); 95 ct.pop(); 96 } 97 ct.push(*iter);//把當前操作符入棧 98 } 99 } 100 } 101 while(!ct.empty()){//如果棧區還有操作符 102 expression += ct.top(); 103 ct.pop(); 104 } 105 cout << "Aft expression is :"; 106 cout << expression << endl; 107 } 108 int sw(char c,int p,int q,int r) 109 { 110 if(c == 'p') 111 return p; 112 else if(c == 'q') 113 return q; 114 else if(c == 'r') 115 return r; 116 return 0; 117 } 118 int compute(int p,int q,int r,string cpu) 119 { 120 stack <int> ans; 121 for(auto it = cpu.begin();it != cpu.end();it++){ 122 if(*it >= 'a' && *it <= 'z') 123 ans.push(sw(*it,p,q,r)); 124 else if(*it == '!'){ 125 int num = ans.top(); 126 ans.pop(); 127 ans.push(!num); 128 } 129 else{ 130 int num1 = ans.top(); 131 ans.pop(); 132 int num2 = ans.top(); 133 ans.pop(); 134 switch(cop(*it)){ 135 case 1: ans.push(num1 == num2);break; 136 case 2: ans.push(num1 || !num2);break; 137 case 3: ans.push(num1 || num2);break; 138 case 4: ans.push(num1 && num2);break; 139 } 140 } 141 } 142 return ans.top(); 143 } 144 string trans1(int p,int q,int r) 145 { 146 int cnt = p * 4 + q * 2 + r; 147 char c = cnt + '0'; 148 string tmp = "m"; 149 tmp += c; 150 return tmp; 151 } 152 string trans2(int p,int q,int r) 153 { 154 int cnt = p * 4 + q * 2 + r; 155 char c = cnt + '0'; 156 string tmp = "M"; 157 tmp += c; 158 return tmp; 159 } 160 void solve() 161 { 162 string s1[10]; 163 string s2[10]; 164 int cnt1,cnt2; 165 cnt1 = cnt2 = 0; 166 cout << "Table:p|q|r|rt" << endl; 167 for(int p = 0;p <= 1;p++) 168 for(int q = 0;q <= 1;q++) 169 for(int r = 0;r <= 1;r++){ 170 cout << " " << p << '|' << q << '|' << r << '|' << compute(p,q,r,expression) << endl; 171 if(compute(p,q,r,expression)) 172 s1[++cnt1] = trans1(p,q,r); 173 else 174 s2[++cnt2] = trans2(p,q,r); 175 } 176 //主析取正規化 177 cout << "Principal Disjunctive Normal Form:\n"; 178 if(cnt1 == 0){ 179 cout << "NULL" << endl; 180 } 181 else{ 182 for(int i = 1;i <= cnt1;i++) 183 cout << " " << s1[i] << endl; 184 } 185 186 //主合取正規化 187 cout << "Principal Conjunctive Normal Form:\n"; 188 if(cnt2 == 0){ 189 cout << "NULL" << endl; 190 } 191 else{ 192 for(int i = 1;i <= cnt2;i++) 193 cout << " " << s2[i] << endl; 194 } 195 } 196 int main() 197 { 198 //輸入邏輯表示式 199 string s; 200 cin >> s; 201 aftExpression(s); 202 solve(); 203 return 0; 204 }