POJ3295 Tautology 表达式计算(数字栈)+构造

参考博客https://blog.csdn.net/llzhh/article/details/52724289

题目链接http://poj.org/problem?id=3295

题意:输入字符串表示逻辑表达式举例(ApNp为 p && !p) 若表达式永远为true,输出Tautology 否则输出not


思路:思考问题

1)如何判断表达式永真? 人脑想法:化简成p||!p 。 机器想法:遍历变量的值(0.1)。本题变量只有pqrst5个,所以时间复杂度 2^5 * o(n)


2)如何计算表达式 例如A10?程序设计时写过计算表达式 X3/21 类型的题,思路是构造数字栈,遍历表达式遇到数字就压栈,遇到运算符就取2个栈元素,运算结果压栈。本题类似

#include<cstdio>
#include<stack>
#include<set>
#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
map<char, int>Map;
int k1, k2, len;
char str[105];

int func()
{
	stack<int> t_num;
	char ch;
	int tmp1, tmp2;
	for(int i = len - 1; i >= 0; i--)
		if(str[i] == 'K' || str[i] == 'A' || str[i] == 'C' || str[i] == 'E')
		{
			tmp1 = t_num.top();
			t_num.pop();
			tmp2 = t_num.top();
			t_num.pop();
			if(str[i] == 'K')
				t_num.push(tmp1 && tmp2);
			else if(str[i] == 'A')
				t_num.push(tmp1 || tmp2);
			else if(str[i] == 'C')
			{
				if(tmp1 == 0 && tmp2 == 1)
					t_num.push(0);
				else
					t_num.push(1);
			}
			else if(str[i] == 'E')
			{
				if(tmp1 == tmp2)
					t_num.push(1);
				else
					t_num.push(0);
			}
		}
		else if(str[i] == 'N')
		{
			tmp1 = t_num.top();
			t_num.pop();
			t_num.push(!tmp1);
		}
		else
			t_num.push(Map[str[i]]);

	tmp1 = t_num.top();
	while(!t_num.empty())
		t_num.pop();
	return tmp1;
}

int main()
{
	int flag;
	while(scanf("%s",str), str[0] != '0')
	{
		len = strlen(str);
		k1 = k2 = 0;
		flag = 1;
		for(int p = 0; p < 2 && flag; p++)
		{
			Map['p'] = p;
			for(int q = 0; q < 2 && flag; q++)
			{
				Map['q'] = q;
				for(int r = 0; r < 2 && flag; r++)
				{
					Map['r'] = r;
					for(int s = 0; s < 2 && flag; s++)
					{
						Map['s'] = s;
						for(int t = 0; t < 2 && flag; t++)
						{
							Map['t'] = t;
							if(func() == 0)
								flag = 0;
						}
					}		
				}		
			}		
		}
		if(flag)
			printf("tautology\n");
		else
			printf("not\n");
	}
	return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值