记录一下数据结构实验课程——重言式
题目
一个逻辑表达式如果对于其变元的任一种取值都为真,则称重言式;反之,如果对于其任一种取值都为假,则称矛盾式;其它情形称为可满足式。编写程序,判断逻辑表达式属于哪种情形。
1.建立逻辑二叉树表达式
2.写一程序,根据逻辑二叉表达式对包括逻辑变量的逻辑表达式进行重言式判别
个人思路
- 首先由四则运算思路联想,先找到最小级运算符,然后左右两边看作整体,进行整体运算。
- 左右两边同样寻找最小级运算符,由此可以进行递归运算,构建二叉树
- 后序遍历,读取二叉树,遇到数字压栈,遇到运算符弹出所需的变量数目。
- 运算弹出的变量,并把结果重新压栈,继续参与计算。
- 值得注意,逻辑表达式需要列出真值表,我通过循环列真值表,每一次循环,计算一次。
- 每一次循环计算若为1,则flag1值变化,0,则flag0变化,
-
最终看这两变量的值判断永真永假还是可满足
代码
#include<iostream>
#include<string>
using namespace std;
typedef struct SNode{
char data;
struct SNode *next;
}SNode,*pSNode;//栈结点
typedef struct Stack{
pSNode top;
}Stack;//栈
void Push(Stack &S,int e){
pSNode p =new SNode;
p->data = e;
p->next = S.top;
S.top = p;
}//入栈
void Pop(Stack &S,int &e){
if(S.top==NULL)
return;
pSNode p = S.top;
e = p->data;
S.top = p->next;
delete p;
}//出栈
typedef struct TreeNode{
char data;
struct TreeNode *lchild,*rchild;
}TNode,*pTNode;//二叉树结点
int FindMinOper(string &T,int start,int end){//找到最小级运算符
int min=-1;
if(start == end){
return start;
}
if(T[start]=='('&&T[end]==')'){//剩下的是括号,返回时去掉括号
return FindMinOper(T,start+1,start-1);
}
for(int i = start ; i <= end ; i++){
if(T[i]=='('){//中间的括号直接跳过
while(T[i]!=')'){
i++;
}
i++;
}
if(T[i]=='&'||T[i]=='|'||T[i]=='!'){
if(T[i]=='|'&&(T[min] != '|' || min == -1)){
min = i;
}
else if(T[i]=='&'&&(T[min] == '!'|| min==-1)){
min = i;
}
else if(T[i]=='!'&&(min==-1)){
min = i;
}
}
}
return min;
}
void creatTree(int start,int end,string &T,pTNode &node){//递归构造二叉树
if(T[start]=='('&&T[end]==')'){
start++;
end--;
}
int min = FindMinOper(T,start,end);
//cout<<"the min:";
//cout<<min<<endl;
node = new TNode;
node->lchild=NULL;
node->rchild=NULL;
node->data = T[min];
if(start<=min-1){//左边还有内容,可以构造左子树
creatTree(start,min-1,T,node->lchild);
}
else{
node->lchild = NULL;
}
if(min+1<=end){//可以构造右子树
creatTree(min+1,end,T,node->rchild);
}
else{
node->rchild = NULL;
}
}
void VisitAndStackAndCal(pTNode &phead,Stack &stack1,int* value){//访问并且计算
int e1;
int e2;
if(phead->lchild){//后序遍历
VisitAndStackAndCal((phead->lchild),stack1,value);
}
if(phead->rchild){
VisitAndStackAndCal((phead->rchild),stack1,value);
}
if(phead->data=='&'||phead->data=='|'||phead->data=='!'){
if(phead->data=='!'){
Pop(stack1,e1);
if(e1==0){
Push(stack1,1);
}
else if(e1==1){
Push(stack1,0);
}
}
else{
if(phead->data=='&'){
Pop(stack1,e1);
Pop(stack1,e2);
//cout<<e1<<"&"<<e2<<endl;
Push(stack1,(e1&&e2));
//cout<<"push"<<(e1&&e2)<<endl;
}
else if(phead->data=='|'){
Pop(stack1,e1);
Pop(stack1,e2);
Push(stack1,(e1||e2));
//cout<<"push"<<(e1||e2)<<endl;
}
}
}
else{
Push(stack1,value[phead->data-'A']);
//cout<<"Push"<<value[phead->data-'A']<<endl;
}
}
void xunhuan(pTNode &phead,Stack &stack1,int* value,int n,int* flag1,int* flag0){
int count = n;
for(int i=0;i<2;i++){//循环列真值表
value[n-1]=i;
//cout<<n<<"the value:";
//cout<<value[n-1]<<endl;
if(count>1){
xunhuan(phead,stack1,value,--count,flag1,flag0);
}
count = n;
if(count==1){
VisitAndStackAndCal(phead,stack1,value);
int ans;
Pop(stack1,ans);
//cout<<"ans:"<<ans<<endl;
if(ans==1){
(*flag1)++;
}
else if(ans==0){
(*flag0)++;
}
}
}
}
void trueth(pTNode &phead,Stack &stack1,int n,int* value,int* flag1,int* flag0){
xunhuan(phead,stack1,value,n,flag1,flag0);
//cout<<"flag1:"<<*flag1<<endl;
//cout<<"flag0:"<<*flag0<<endl;
if(*flag1>-1&&*flag0>-1){
cout<<"satisfied"<<endl;
}
else if(*flag1>-1&&*flag0==-1){
cout<<"always true"<<endl;
}
else if(*flag1==-1&&*flag0>-1){
cout<<"always false"<<endl;
}
}
int main(){
int n;//几个变量;
int flag0= -1,flag1=-1;
cout<<"put the number of variable"<<endl;
cin >> n;
int* value = new int[n];
string str;
Stack stack1;
Stack stack2;
pTNode Thead = NULL;
stack1.top = NULL;//存放变量
stack2.top=NULL;
cout<<"put the logical expression"<<endl;
cin.get();
getline(cin,str);
int start = 0;
int end = str.length()-1;
creatTree(start, end,str,Thead);//构造二叉树
trueth(Thead,stack1,n,value,&flag1,&flag0);//后序遍历并入栈判断
system("pause");
return 0;
}