重言式判别(栈和二叉树)
问题描述
一个逻辑表达式如果对于其变元的任一种取值都为真,则称重言式;反之,如果对于其任一种取值都为假,则称矛盾式;其它情形称为可满足式。编写程序,判断逻辑表达式属于哪种情形。
设计要求
1.建立逻辑二叉树表达式
2.写一程序,根据逻辑二叉表达式对包括逻辑变量的逻辑表达式进行重言式判别
思路分析
问题的关键式表达式二叉树的建立,建立表达式二叉树有两种方式
递归建立表达式二叉树
代码的核心思想是:找到表达式中最后使用的操作符,作为二叉树根节点,左侧右侧递归生成的二叉树分别为左孩子和右孩子,如果优先级最低的操作符有多个,就取最右边的那个。该方法的优点是代码简单,思路清晰,缺点是要自己动手写!因为我写的时候没找到相关的代码,因此我参考了另一种方法,这里给出一篇大神写的博客供大家参考思路递归建立表达式二叉树
借助栈建立二叉树
差不多就是这样的思路,想更详细的了解表达式二叉树的建立可以看这篇文章数据结构与算法 表达式二叉树
当然了解了表达式二叉树的建立之后,还要把它改编成逻辑表达式二叉树这里就不多叙述了,关键是思路。
根据二叉树得到真值表
得到了二叉树之后,要对变量进行赋值和表达式值的计算,那么我们就需要一个函数得到变量的个数。现在假设有三个变量ABC,他们取不同的值对应的真值表刚好是0-7的二进制表示那么就可以用一个循环对表达式中的ABC赋值并算出每种情况下的真值,最后根据真值表判断是不是重言式就好了。
完整代码
//
// main.cpp
// test
#include <iostream>
#include <string>
using namespace std;
typedef struct TreeNode{
char data;
int value;
struct TreeNode *lchild;
struct TreeNode *rchild;
}*Bitree;
struct Stack
{
Bitree *base;
int top;
int size;
};
void InitStack(Stack &s){
s.base = new Bitree[50];
s.top = 0;
s.size = 50;
}
void push(Stack &s,Bitree &node){
if(s.top >= s.size){
Bitree *newbase;
newbase = new Bitree[s.size + 10];
for(int j = 0;j < s.top; j++){
newbase[j] = s.base[j];
}
delete[] s.base;
s.base = newbase;
s.size += 10;
}
s.base[s.top++] = node;
}
bool empty(Stack &s){
return s.top == 0;
}
bool pop(Stack &s,Bitree &node){
if(empty(s)){
return false;
}
node = s.base[--s.top];
return true;
}
bool Gettop(Stack s,Bitree &node){
if(!empty(s)){
node = s.base[s.top - 1];
return true;
}else return false;
}
//栈的定义
bool JudgeSimbol(char &c){
switch(c){
case'|':
case'&':
case'~':
case'(':
case')':
case'=':return true;
default:return false;
}
}
bool JudgeNum(char &c){
if(c == '0'|| c == '1') return true;
else return false;
}
bool JudgeCaps(char &c){
//检查大写字母
if(c >= 'A'&&c <= 'Z') return true;
else return false;
}
int JudgeCin(string c){