目录
一、实验背景
二、实验目的
三、实验内容
四、相关知识
五、实验代码
一、实验背景
离散数学前几课时课时便是关于命题逻辑的学习,谈到命题逻辑的各种指派与对应值,比较详细且直观的便是真值表表示,那如果现在给出一个命题公式,我们该如何通过编程的方式实现一个能够自动生成给出命题公式所对应的真值表呢?离散数学课便设计了实验让我们探索如何实现此功能,在加深对命题公式理解的同时提高编程能力,培养编程思维。
二、实验目的
1、掌握基本联结词的真值表。
2、掌握命题公式真值表的计算方法。
3、设计逆波兰表达式求值的合理数据结构及方法,并使用C++实现。
4、设计生成命题公式真值表的合理数据结构及方法,并使用C++实现。
三、实验内容
PropositionalFormular类:
成员变量:
m_strPropFmlr - 命题公式
m_strRevertPolishNotation - 命题公式对应的逆波兰表达式
m_OperatorStack - 用来存储联结词的栈
m_PriorityMap - 静态成员。这是一个的map,用联结词作为key,用联结词的优先级做为value。value值越大,表示优先级越高。
m_OperandStack - 用于存储操作数的栈。该栈在解析逆波兰式时暂存操作数(即命题变元和常元)
m_vecTableTitle - 真值表表头。假设向量中有n个元素,前n-1个为命题变元,第n个元素为命题公式。例如,对于公式P&Q>R,该向量有4个元素,依次为P、Q、R、P&Q>R。注意:命题公式中可能存在命题常元T和F,注意特殊处理。
另外,应该意识到:m_vecTableTitle.size() - 1 = 公式中命题变元的数量
这里规定命题变元的数量不超过16个
成员函数:
Convert2RPN() - 将命题公式m_strPropFmlr转换为逆波兰式,请注意将得到的逆波兰式存储在m_strRevertPolishNotation中。
PropositionalFormular() - 默认构造函数。
~PropositionalFormular() - 析构函数。
PropositionalFormular(string formular) - 构造函数。该构造函数将m_strPropFmlr初始化为formular,并调用Convert2RPN()将命题转换为逆波兰式
FillTableTitle() - 解析命题公式m_strPropFmlr,生成真值表表头m_vecTableTitle。例如,对于命题公式 P&Q>T,由于T是命题常元,所以该命题公式中有两个变元,所以解析后m_vecTableTitle中应该有三个元素:P、Q、P&Q>T
EvalRPN(map varvals) - 计算并返回逆波兰表达式的值。其中varvals存储的是命题公式的一种指派。例如,对于命题公式 P&Q>T,其中有两个命题变元,当P = false,Q = true,则varvals['P'] = false,varvals['Q'] = true
GenerateTrueValueTable() - 生成并输出命题公式的真值表。以P&Q>T为例,要求输出格式如下:
P Q P&Q>T
0 0 1
1 0 1
0 1 1
1 1 1
注意:各列之间以制表符('\t')分隔。
提示:真值表的每一行的前n-1列实际是该公式的一种指派。而每一行的最后一列对应一个逆波兰式的值,这个值是用EvalRPN(map varvals)来求。参数varvals中存储的就是这个指派。
ClearOperatorStack() - 清空运算符栈。在把中缀表达式转为逆波兰式之前调用。
ClearOperandStack() - 清空操作数栈。在对逆波兰表达式求值之前调用。
CalcConjunction(bool left, bool right) - 返回left与right的合取
CalcCompatileDisjunction(bool left, bool right) - 返回left与right的析取
CalcNegation(bool right) - 返回right的否定
CalcImplication(bool left, bool right) - 返回left->right的真值
关于命题公式和命题联结词的说明:
1、每个命题变元由一个大写字母表示;
2、为简化问题,本实验只考虑否定、合取、析取、条件四种联结词。
3、每种联结词用一个字符表示,分别是:否定('!')、合取('&')、析取('|')、条件('>')。
4、命题公式中可能存在括号。具体实例可见主函数。
5、命题公式中可能存在命题常元:T和F,注意特殊处理。
6、这里规定命题变元的数量不超过16个。
注意:所有字符均为半角字符(英文输入法)。
四、相关知识
逆波兰表达式求值算法
首先需要设置一个暂存操作数的栈(下文简称为栈),将其初始化为空。然后从左到右,对逆波兰表达式进行逐字符处理如下:
(1)若当前字符为操作数,则直接将其真值入栈;
(2)若当前字符为命题联结词,则根据不同的联结词,取出栈顶的1(否定联结词)或2(合取、析取、条件联结词)个操作数与联结词结合,求值后,将结果入栈。
当逆波兰式扫描结束后,栈中只有一个元素,该元素即为表达式的值。
下面以
( 逆波兰式为
)为例,对求值过程图解如下

五、实验代码
#include
#include
#include
#include
注:这个码要是用来交实验的话可不能全抄,不然有什么后果本人概不负责,觉得好的话可以点赞支持来激发我的动力