重言式判别.docx

上传人:b****2 文档编号:24542162 上传时间:2023-05-28 格式:DOCX 页数:14 大小:130.19KB
下载 相关 举报
重言式判别.docx_第1页
第1页 / 共14页
重言式判别.docx_第2页
第2页 / 共14页
重言式判别.docx_第3页
第3页 / 共14页
重言式判别.docx_第4页
第4页 / 共14页
重言式判别.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

重言式判别.docx

《重言式判别.docx》由会员分享,可在线阅读,更多相关《重言式判别.docx(14页珍藏版)》请在冰豆网上搜索。

重言式判别.docx

重言式判别

重言式判别

一、问题描述

一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。

试写一程序,通过真值表判断一个逻辑表达式属于那一类。

二、需求分析

(1)逻辑表达式从终端输入,长度不超过一行。

逻辑运算符包括“|”,“&”和“~”,

分别表示或、与和非,运算优先程度递增,但可以有括号改变,即括号内的运算优先。

逻辑变元为大写字母。

表达式中任何地方都可以含有多个空格符。

(2)若是重言式或矛盾式,可以只“显示Trueforever”或“Falseforever”,否则显示“Satisfactible”以及变量名序列,与用户交互。

若用户对表达式中变元取一组值,程序就求出并显示逻辑表达式的值。

(3)测试数据:

①(A|~A)&(B|~B)

②(A&|~A)&C

③A|B|C|D|E|~A

④A&B&C&~B

⑤(A|B)&(A|~A)

⑥A&~B|~A&B

三、概要设计

voidcreatzuhe(intn)

初始条件:

n是循环体,以便产生各种情况。

操作结果:

产生变量的各种取值组合。

voidcreate(bitree&root,bitreel,bitreer)

初始条件:

root是根结点,l是左子树,r是右子树。

操作结果:

按照运算符优先级关系建立二叉树。

charyouxianji(charlie,charhang)

初始条件:

lie是第一个运算符,hang是第二个运算符。

操作结果:

得出优先级比较关系。

voidcreatstack(sqstack&st)

初始条件:

若栈st存在。

操作结果:

把栈置空。

voidpush(sqstack&st,bitreee)

初始条件:

若栈st存在,对树结点e操作。

操作结果:

把操作符入栈。

voidpop(sqstack&st,bitree&e)

初始条件:

若栈st存在,对树结点e操作。

操作结果:

把操作符出栈。

voidGettop(sqstack&st,bitree&e)

初始条件:

若栈st存在,对树结点e操作。

操作结果:

取栈顶元素。

voidcreattree(chars[],bitree&tree)

初始条件:

是s[]存放运算符,tree是按照运算符优先级建立的二叉树。

操作结果:

判断重言式。

intvalue_tree(bitreetree)

初始条件:

tree是按照运算符优先级建立的二叉树。

操作结果:

对逻辑表达式求值。

算法思想:

自底向上地根据运算符地优先级来建立分子树函数;当逻辑表达式读完后-子根root就是一棵完整的二叉树。

用穷举法得出所有可能组合,对二叉树进行先序遍历,对存放在上面的表达式进行求值。

并用两个栈分别存放运算符和变量,来判别是否为重言式。

四、程序实现关键代码

typedefstructbtdnode{

chardata;

structbtdnode*lchild;

structbtdnode*rchild;

}*bitree;

//识别表达式使用的堆栈定义,它存放的都是树的结构;

typedefstructStack{

structbtdnode**base;//栈中的元素都是树的结点结构;

structbtdnode**top;

intstacksize;

}sqstack;

//用于产生变量的各种取值组合;

voidcreatzuhe(intn)

{

inti,num=0,j=0,e;

inttemp[max];

for(i=0;i

zuhe[i]=0;

while(n)

{

e=n%2;

num++;

temp[j++]=e;

n=n/2;

}

j=j-1;

num=N-num;

while(j>=0)

{

e=temp[j--];

zuhe[num++]=e;

}

}

//自底向上地根据运算符地优先级来建立分子树函数;当逻辑表达式读完后-子根root就是一棵完整的二叉树

intk=0;//建树的标志,k=1表示第一次建立分子树,要对左右孩子的指针域处理

voidcreate(bitree&root,bitreel,bitreer)

{

root->lchild=l;

root->rchild=r;//分树的链接

if(l&&r)

{

if(int(l->data)>=65&&int(l->data)<=90)

{

l->lchild=NULL;

l->rchild=NULL;

}

if(int(r->data)>=65&&int(r->data)<=90)

{

r->lchild=NULL;

r->rchild=NULL;

}

}

}

//逻辑运算符的优先级判别;

charyouxianji(charlie,charhang)

{

inti,j;

charbijiao[7][7]={'','|','&','~','(',')','#',

'|','>','<','<','<','>','>',

'&','>','>','<','<','>','>',

'~','>','>','>','<','>','>',

'(','<','<','<','<','=','',

')','>','>','>','','>','>',

'#','<','<','<','<','','='};

for(j=0;j<7;j++)

if(bijiao[0][j]==lie)

break;

for(i=0;i<7;i++)

if(bijiao[i][0]==hang)

break;

returnbijiao[i][j];

}

//对操作符栈和变量堆栈的操作;

voidcreatstack(sqstack&st)//置空栈

{

st.base=(bitree*)malloc(stack_size_normal*sizeof(btdnode));

st.top=st.base;

st.stacksize=stack_size_normal;

}

voidpush(sqstack&st,bitreee)//入栈

{

if(st.top-st.base

*st.top++=e;

}

voidpop(sqstack&st,bitree&e)//出栈

{

e=*--st.top;

}

voidGettop(sqstack&st,bitree&e)//栈顶元素

{

e=*(st.top-1);

}

/////////////////////////////////////////////////////////////////////////////////

//重言式的识别函数;

voidcreattree(chars[],bitree&tree)

{

sqstackBiangliang_Stack;//变量栈;

sqstackYunsuan_Stack;//逻辑运算符栈;

creatstack(Biangliang_Stack);//变量栈的初始化;

creatstack(Yunsuan_Stack);//逻辑运算符栈初始化;

bitreelogic_di,variables,logics,e,a,b,theta,kuohao;//定义栈中的元素,theta为最后的二叉树的根

logic_di=(bitree)malloc(sizeof(btdnode));//定义新空间

logic_di->data='#';//令运算符栈顶元素为'#'

push(Yunsuan_Stack,logic_di);//运算符入栈

while(*s!

=NULL)//输入数据不为空

{

if(int(*s)>=65&&int(*s)<=90)//且在大写字母A~Z之间(限定为A~Z)

{

variables=(bitree)malloc(sizeof(btdnode));

variables->data=*s;

push(Biangliang_Stack,variables);

}

elseif(int(*s)>90||int(*s)<65)

{

Gettop(Yunsuan_Stack,e);//取运算符栈的栈顶元素进行优先级比较

switch(youxianji(*s,e->data))//优先级比较

{

case'<':

//栈顶的运算符优先级低,逻辑运算符进栈

logics=(bitree)malloc(sizeof(btdnode));

logics->data=*s;

push(Yunsuan_Stack,logics);//如果ASC码小于,则入栈

break;

case'=':

pop(Yunsuan_Stack,kuohao);//脱括号并接受下一个字符;

break;

case'>':

//如果ASC码大于,则运算符和变量出栈

pop(Yunsuan_Stack,theta);//弹出逻辑运算符

pop(Biangliang_Stack,a);//弹出变量

b=NULL;

if(theta->data!

='~')//如果根结点的值大于"~"

pop(Biangliang_Stack,b);//弹出变量

//建树的函数调用

k=k+1;

create(theta,b,a);//建立二叉树

push(Biangliang_Stack,theta);//将临时的根作为新的变量压入变量栈中;

if(*s!

='#'&&*s!

=')')//(作用是当输入一个元素是运算符时,将其入栈,否则该运算符无法运算)

{

logics=(bitree)malloc(sizeof(btdnode));

logics->data=*s;

push(Yunsuan_Stack,logics);//入运算符栈

}

elses=s-1;//(防止在开头连续输入相同两个运算符,如果连续输入两个运算符,只能对第一个运算符进行运算)

break;

}

}

s++;

}

tree=theta;

}

//根据变量的取值组合并利用逻辑表达式的性质对树进行求值

intvalue_tree(bitreetree)

{

if(!

tree)return0;//遇到空的结点;

elseif(tree->data!

='|'&&tree->data!

='&'&&tree->data!

='~')//找到的是变量;

returnzuhe[int(tree->data)-65];

elseif(int(tree->data)<65||int(tree->data)>90)//找到的是运算符;

switch(tree->data)

{

case'|':

return(value_tree(tree->lchild)||value_tree(tree->rchild));//如果是或,则将左子树和右子树进行或运算

case'&':

return(value_tree(tree->lchild)&&value_tree(tree->rchild));//如果是与,则将左子树和右子树进行与运算

case'~':

return(!

value_tree(tree->rchild));////如果是非,则将左子树和右子树进行非运算

}

}

 

五、调试分析

刚开始将程序编译到无错误时发现无法出现结果。

DEBUG调试发现变量根本没有附值,所以设计一个zuhe函数,将每个变量给值0或1,得出了结果。

由于将栈清空,所以每次读到第一个运算符时总要将其入栈,很麻烦,所以决定在栈放入“#”号,这样就只要判别优先级就可以决定进出栈。

发现连续输入两个运算符就会出现无法运行的情况,找到程序位置禁止连续输入相同的符号,使程序可读性更好。

六、测试结果和分析

测试数据①(A|~A)&(B|~B)

当A、B取值为0,0;0,1;1,0;1,1;时表达式的值分别为1,1,1,1,为重言式。

测试数据②(A&|~A)&C

当A、C取值为0,0;0,1;1,0;1,1;时表达式的值分别为0,0,0,0,为矛盾式。

测试数据③A|B|C|D|E|~A

测试结果为重言式。

测试数据④A&B&C&~B

测试结果为矛盾式。

⑤(A|B)&(A|~A)

测试结果为非重言式和矛盾式。

测试数据⑥A&~B|~A&B

测试结果为非重言式和矛盾式。

从以上六个测试用例来看,结果正确。

但是程序还有一些有待解决的问题。

比如,表达式中没有解决空格的问题,当有空格存在,就无法继续下去。

另一个问题是表中显示的大写字母和表达式中的大写字母不对应,只是机械的按照次序。

但总的来说程序已经比较完善,书上的要求也基本符合,并且加入了对矛盾式的判别。

七、感想与建议

重言式是离散数学中一个很重要的概念,原本我以为这个程序会相对比较简单。

但在编的过程中明显发现了困难。

它运用到了二叉树存储结构,还利用了栈的概念对变量和运算符分别保存。

充分运用了我们学过的知识,对我们之前实验所做的很多东西进行了总结。

这个实验不仅仅是一次课程设计,更是对我们整个数据结构的第二章和第六章的复习,具有很重要的锻炼价值。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 交通运输

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1