ssd做逻辑

时间限制: 1000 ms 内存限制: 65536 kb
总通过人数: 0 总提交人数: 0

题目介绍

ssdcbd助教一起上了一门课,课内常有逻辑表达式证明的作业,ssd学长实在是太菜了,没办法看清楚这些表达式的值,想请你写个程序画出这些表达式对应的真值表,求求你帮帮他。

真值表是什么?

对于只能取的简单命题变元,通过逻辑连接词(例如)等连接起来的表达式称为命题

表征命题在所有输入可能取值状态下对应的值的表格即为真值表。

例如现在有两个简单命题变元pq,通过逻辑连接词$\wedge$连接为命题$p \wedge q$,则该命题的真值表即为

$p$$q$$p\wedge q$
FFF
FTF
TFF
TTT
  • 对于逻辑连接词而言,满足一元逻辑连接词优先于二元运算连接词,二元运算连接词之间优先级相同,但如果存在括号,则括号内的优先级最高

  • 命题的同优先级的演算遵循从左到右的规则

输入格式

两行输入

第一行为多个字母,由空格隔开,表示这一组数据中的出现的简单变元的字符 (简单变元字符仅可能为小写字母,保证不会重复)

第二行为一行逻辑表达式,由第一行中出现过的字符和逻辑连接词组成,为方便大家表示,本题规定逻辑连接词包括&,|,~,(,)

其意义如下

  • &:与运算
  • |:或运算
  • ~:非运算
  • (:左括号
  • ):右括号

输出格式

令输入的简单变元个数为$n$(这个$n$需要大家自己计数)

则总输出为$2^n+1$行,每行$n+1$列,列于列之间以|隔开,列内容与|符号之间留出一个空格

第一行为表头,前$n$列为输入的简单命题变元字符,第$n+1$列为$R$,代表Result

接下来$n$行,每行代表每种取值可能对应的命题结果,真以T表示,假以F表示

输入顺序满足命题变元代表的二进制数的升序,以包括四个简单命题变元的命题为例

FFFF0000代表0,则首先输出,FFFT0001代表1,第二个输出,依次类推,直到所有情况输出完成

输入样例1

p q
p&q

输出样例1

| p | q | R |
| F | F | F |
| F | T | F |
| T | F | F |
| T | T | T |

输入样例2

p q r
(((p&~q)|(~p&q))&~r)|(~((p&~q)|(~p&q))&r)

输出样例2

| p | q | r | R |
| F | F | F | F |
| F | F | T | T |
| F | T | F | T |
| F | T | T | F |
| T | F | F | T |
| T | F | T | F |
| T | T | F | F |
| T | T | T | T |

数据范围

给出的简单命题变元不会超过$10$个

命题中逻辑连接词+命题变元长度不超过300个

HINT

本题输入末尾存在'\r'字符,请想办法消除它的干扰

用栈可以解决表达式计算的问题

样例2是全加器的本位数真值哦嘻嘻

如果你不知道怎么遍历命题变元的各种取值可能的话,去E2请教一下木木枭学长吧!

Author:ssd

如果你已经有了完成这一任务的思路,请忽略下面的提示

下面给出用栈计算包含(+,-,*,/)算数表达式的思路

(考虑括号的话要怎么样做呢?)

以表达式1+2*3-4/5为例

首先,我们建立两个栈分别为数字栈与符号栈

向数字栈中压入第一个数字1

判断符号栈为空,直接压入一个运算符+

再向数字栈中压入一个数字,为2

判断符号栈非空,判断待压字符与栈顶字符的优先级,*优先于+,将*压入字符栈

向数字栈中压入下一个数字3

判断符号栈非空,判断待压字符与栈顶字符优先级,-号的优先级低于*,暂缓压栈

弹出数字栈中顶部两个数字,弹出符号栈中的*号,计算2*3=6,将结果6压入数字栈

重复判断符号栈非空,判断顶部符号于-的优先级和+号相同,继续暂缓压栈

弹出数字栈中顶部两个数字1和6,弹出符号栈的+,计算1+6=7,将7压入数字栈

判断符号栈为空,压入-号

压入数字4

判断符号栈非空,判断待压运算符 / 与 - 的优先级, / 的优先级高于 - ,压入 / 号

向数字栈压入数字5

此时以及没有待读取的字符了,开始回溯栈中的信息

判断字符栈非空,弹出两个数字5和4,弹出符号 / 计算4/5=0.8,将0.8压入数字栈.

判断字符栈非空,弹出数字0.8和7,弹出 - 号,计算 7-0.8-6.2,将6.2压入数字栈

此时字符堆栈已空,弹出数字栈顶的数字,此时数字栈中唯一的数字即为结果6.2

相关推荐