//寒假,离散老师说,把几个程序实现一下。但是在家里都没怎么去看。花了点时间结束。
思路:
1、求解最后的真值,一般可以用栈,二叉树,当然还有其他方法。(可以参考:http://www.cnblogs.com/U2USoft/archive/2009/03/26/1422545.html)
2、个人觉得麻烦的地方是,模拟离散数学中的真值表计算的过程。它并不是从左到右直接计算的。而是按照层次。优先级高的先计算,然后计算次优先级的,直到计算完整个表达式。模拟的程序要求输出每层运算的结果。
离散数学书上,真值表计算具体步骤要求如下:
a,找出公式中的所含的全体命题变量,列出2^n个赋值
b,按从高到低的顺序写出公式的各个层次;
c,对应各个赋值计算出各个层次的真值,直到计算公式的真值
下面有个程序输出的例子。(打印的输出暂默认>为->)_______________________________________________
请输入逻辑表达式,回车结束...
^(p->q)&q&r
真值表如下:
________________________________________________
p q r p>q ^(p>q) (^(p>q)&q) ((^(p>q)&q)&r)
0 0 0 1 0 0 0
0 0 1 1 0 0 0
0 1 0 1 0 0 0
0 1 1 1 0 0 0
1 0 0 0 1 0 0
1 0 1 0 1 0 0
1 1 0 1 0 0 0
1 1 1 1 0 0 0
________________________________________________
要继续计算? (y:是 n:否)
你的选择:
解决关键:
主要要找到每层的每个子命题(子公式),然后依次计算保存。
建立表达式二叉树,从树节点的深度(这里的叶子节点的深度最小)就可以知道它的层次,按树节点的深度从小到大选择树节点,依次计算这个深度下的所有树节点及其一下的节点构成的命题。这样就保证“层次”计算的要求。保存的每个表头,就是子命题公式(如^(p>q))。从表达式树回到表达式时要注意括号和^。最后打印就可以啦。此外打印时候,注意对齐方式。
本来是想每个子命题的运算完后,接着利用其计算结果继续计算大一点的子命题,以此扩展到整个明天的计算,但是好像有点烦,就放弃了。还是采用重复计算。
下面是一个真值表类的头文件:
[code=C++]
/
// filename: truth_table.h
// Author: feng02
// purpose: 真值表类以及实现
// 用于将输入的公式命题在所有的赋值情况列成表
// 包括的联结词有(、)、&、|、^、->、<->;
// Main functions: SubStr,Evaluate,CreateExprBinTree等
// Edition: *V3[2010/3/22] V1[2010/3/3] V2[2010/3/13]
// modification : 1、修改添加函数,实现真值表的每层运算的输出
// 2、修改了函数的参数,便于重用
// References: 参考计算器程序,写了计算部分