题目链接:http://poj.org/problem?id=3295
思路分析:判断逻辑表达式是否为永真式问题。根据该表达式的特点,逻辑词在逻辑变量前,类似于后缀表达式求值问题。
算法中使用两个栈,从表达式的后边开始处理表达式中每个字符;若为逻辑变量,使其入栈SR,否则从栈SR中弹出两个逻辑变量,
进行运算后的结果再入栈SR;直到处理完表达式所有的字符。(PS:使用栈可以很好的处理广义表类似的序列)
代码如下:
#include <iostream> #include <stack> using namespace std; const int MAX_N = 1000 + 10; char A[MAX_N]; int p, q, r, s, t, ans; int Match(char x) { int value = 0; switch(x) { case '0':value = 0; break; case '1':value = 1; break; case 'p':value = p; break; case 'q':value = q; break; case 'r':value = r; break; case 's':value = s; break; case 't':value = t; break; default: value = p; } return value; } int Calc(char a, char b, char T) { int x, y, ans; x = Match(a); y = Match(b); switch(T) { case 'K':ans = x && y; break; case 'A':ans = x||y; break; case 'N':ans = !x; break; case 'C':ans = (!x)||y; break; case 'E':ans = (x == y);break; } return ans; } int WWF( ) { int Rusult = 0; int Len = strlen(A); stack<char>SL, SR; for (p = 0; p <= 1; ++ p) for(q = 0; q <= 1; ++ q) for(r = 0; r <= 1; ++ r) for(s = 0; s <=1; ++ s) for(t = 0; t <= 1; ++ t){ for (int i = 0; i < Len; ++ i) SL.push(A[i]); while (!SL.empty()) { char x, y, T; int flag = 0; T = SL.top();SL.pop(); switch(T) { case 'p': case 'q': case 'r': case 's': case 't': SR.push(T);flag = 1;break; } if (flag == 1) continue; else if (T == 'N') { x = SR.top();SR.pop(); ans = Calc(x, x, T); } else { x = SR.top();SR.pop(); y = SR.top();SR.pop(); ans = Calc(x, y, T); } SR.push(ans + '0'); } if (ans == 0) return 0; } return 1; } int main() { int flag = 0; while (scanf( "%s", A ) != EOF) { if (A[0] == '0') break; flag = WWF(); if ( flag == 0 ) printf( "not " ); else printf( "tautology " ); } return 0; }