本題雖然簡單,但是利用了編譯原理裡面的自頂向下方法來設計語法樹,遞歸求解。
例如:對於邏輯表達式A&B|C,得到以下輸出
A B C A&B|C
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1
邏輯表達式支持:常量(只有0和1兩種常量)、變量(用一個大寫字母表示,因此最多26個變量)、“與”運算、“或”運算、“非”運算
用算符優先文法來做語法解析。優先級比較表如下:
| & ! ( ) #
| > < < < > <
& > > < < > <
! > > > < > <
( < < < < = <
) > > > E > <
# > > > > > =
算符優先文法解析方式:
1、定義優先級比較表。除了真正需要使用的運算符。
2、使用了一個棧,只用於存放操作數(Operand)
3、若當前優先級小於棧頂優先級,則規約;若大於,則入棧。
則不難寫出以下代碼:
#include <iostream> #include <stack> #include <string> using namespace std; stack <int> stk; bool isvariable(char c, int pp, int qq, int rr, int ss, int tt) { switch (c) { case 'p': stk.push(pp); return true; case 'q': stk.push(qq); return true; case 'r': stk.push(rr); return true; case 's': stk.push(ss); return true; case 't': stk.push(tt); return true; } return false; } void operand(char op) { switch (op) { case 'K': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x && y); break; } case 'A': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x || y); break; } case 'C': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push((!x) || y); break; } case 'E': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x == y); break; } case 'N': { int x = stk.top(); stk.pop(); stk.push(!x); break; } } return; } int main() { string s; while (cin >> s && s != "0") { bool flag = true; for (int pp = 0; pp <= 1; ++pp) { for (int qq = 0; qq <= 1; ++qq) { for (int rr = 0; rr <= 1; ++rr) { for (int ss = 0; ss <= 1; ++ss) { for (int tt = 0; tt <= 1; ++tt) { for (int i = s.size() - 1; i >= 0; i--) { if (!isvariable(s[i], pp, qq, rr, ss, tt)) operand(s[i]); } int ans = stk.top(); stk.pop(); if (!ans) { flag = false; break; } } if (!flag) break; } if (!flag) break; } if (!flag) break; } if (!flag) break; } if (flag) { cout << "tautology" << endl; } else cout << "not" << endl; while (!stk.empty()) { stk.pop(); } } } #include <iostream> #include <stack> #include <string> using namespace std; stack <int> stk; bool isvariable(char c, int pp, int qq, int rr, int ss, int tt) { switch (c) { case 'p': stk.push(pp); return true; case 'q': stk.push(qq); return true; case 'r': stk.push(rr); return true; case 's': stk.push(ss); return true; case 't': stk.push(tt); return true; } return false; } void operand(char op) { switch (op) { case 'K': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x && y); break; } case 'A': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x || y); break; } case 'C': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push((!x) || y); break; } case 'E': { int x = stk.top(); stk.pop(); int y = stk.top(); stk.pop(); stk.push(x == y); break; } case 'N': { int x = stk.top(); stk.pop(); stk.push(!x); break; } } return; } int main() { string s; while (cin >> s && s != "0") { bool flag = true; for (int pp = 0; pp <= 1; ++pp) { for (int qq = 0; qq <= 1; ++qq) { for (int rr = 0; rr <= 1; ++rr) { for (int ss = 0; ss <= 1; ++ss) { for (int tt = 0; tt <= 1; ++tt) { for (int i = s.size() - 1; i >= 0; i--) { if (!isvariable(s[i], pp, qq, rr, ss, tt)) operand(s[i]); } int ans = stk.top(); stk.pop(); if (!ans) { flag = false; break; } } if (!flag) break; } if (!flag) break; } if (!flag) break; } if (!flag) break; } if (flag) { cout << "tautology" << endl; } else cout << "not" << endl; while (!stk.empty()) { stk.pop(); } } }