POJ3295——Tautology

POJ3295


/*

***********************************************************
算法原理:
WFF求值,从表达式的末尾向前读取字符,并分类出入栈。因为输入
是合法的,最后栈顶(且只有一个)的元素即为表达式的逻辑值

Notice:
1)位&运算符的运用,可以精简代码
2)判断K, A, N, C, E的逻辑值可以用已知二维数组
3)还可以用递归求解

***********************************************************
*/
#include<iostream>
#include<stack>

using namespace std;

const int Length = 1000;
stack<int> answers;
char experssion[Length];
int value[5];												//在共2^5(32)种情况下判断
void  operaterStack(int pos)								//根据expression进行出入栈的操作
{
	if (experssion[pos] == 'N')
	{
		int a = answers.top(); answers.pop();
		answers.push(!a);
	}
	else if (experssion[pos] >= 'p'&&experssion[pos] <= 't')
		answers.push(value[experssion[pos] - 'p']);			//value[0]-value[4]在32个循环里赋予了不同的值
	else
	{
		int a = answers.top(); answers.pop();
		int b = answers.top(); answers.pop();
		switch (experssion[pos])
		{
		case 'K':answers.push(a&&b); break;					//或者按题目中给的bool值,用已知数组判断逻辑关系
		case 'A':answers.push(a || b); break;
		case 'C':answers.push(!a|| b); break;
		case 'E':answers.push(a == b); break;
		default:break;
		}
	}
}
int main()
{
	while (cin >> experssion&&(experssion != "0"))			//表达式结束的标志位'0'
	{
		int j;
		for (j = 0; j < (1 << 5); j++)						//共32种情况
		{													//详细见图
			for (int k = 0; k < 5; k++)						
				value[k] = j & (1 << k);					//类似于x&1判断奇偶

			int i = strlen(experssion);						//while循环的条件有i--防止越界
			while (i--)
				operaterStack(i);							//value[0]-value[4]在这个函数里发挥作用啦
			if (!answers.top())
			{
				cout << "not\n";							//栈顶元素即为表达式最后的值
				answers.pop();								//清空栈,给下一次循环使用
				break;
			}
		}
		if (j >= (1 << 5))									//如果j是正常退出,即说明表达式值为1
			cout << "tautology\n";							//此时j>=32
	}
}

/*
非常酷的用递归的写法,在32个循环中判断即可

int getval()
{
	int temp1, temp2;
	switch (experssion[pos++])
	{
	case 'p': return (value & (1 << 0)) ? 1 : 0;
	case 'q': return (value & (1 << 1)) ? 1 : 0;
	case 'r': return (value & (1 << 2)) ? 1 : 0;
	case 's': return (value & (1 << 3)) ? 1 : 0;
	case 't': return (value & (1 << 4)) ? 1 : 0;

	case 'K': temp1 = getval(); temp2 = getval(); return temp1 & temp2;
	case 'A': temp1 = getval(); temp2 = getval(); return temp1 | temp2;
	case 'N': return !getval();
	case 'C': temp1 = !getval(); temp2 = getval(); return temp1 | temp2;
	case 'E': temp1 = getval(); temp2 = getval(); return temp1 == temp2;
	}
 }
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值