您的位置:首页 > 理论基础 > 数据结构算法

重言式判别 (数据结构课程设计)

2007-11-13 17:54 1026 查看
花了一下午在写这个重言式判别,可能是我孤陋寡闻了,总感觉这个名字怪怪的,就是判断一个永真式、永假式、可满足式了,书上面就要说是"重言式"。判断这个所谓重言式,核心算法就是用真值表啦,试过所有取值。

具体代码如下(可能有bug):有些难理解的我都有注释




/**//********************************************************************


created: 2007/11/09




author: 刺猬





purpose: 判断表达式的属性 永真式 永假式 可满足式


*********************************************************************/


#include<stdio.h>


#include<stdlib.h>








typedef struct exp...{


char data;


int weight;


}express;






express symbolrepresent[27];


express originalexpression[50];




int trueforever=0;


int falseforever=0;


int originalexpressionlength =0;


int symbolrepresentlength=0;




//欢迎屏幕


void ShowWelcome()




...{


printf(" ");


printf(" ");


printf(" ");


printf(" ");


printf(" * * * * * * * * * * * * * * * * * * * * * * * * ");


printf(" * 数据结构课程设计: * ");


printf(" * * * * * * * * * * * * * * * * * * * * * * * * ");


printf(" ");


printf(" 06052711班 ");


printf(" 刺猬 ");


printf(" ");


}




//表达式分析器 分析权值 把 | 权值设为1 &设为2 ~设为3
//处理括号的思路是:遇见左括号 把里面权值提升4 遇见右括号 把权值减去4 这样可以处理多括号问题




int analyse(express *p)




...{


int weight=0;


int length=0;


printf("请输入表达式,并以回车符为结束: ");


printf("注意:请自行检查输入表达式的正确性 ");


while(scanf("%c",&(p->data))&&p->data!=10)




...{


if(p->data>=97&&p->data<=122)


p->data=p->data-32;


switch(p->data)




...{


case '(':


weight=weight+4; //遇见左括号 把里面权值提升4


p->weight=0; //注意括号权值为0


break;


case ')':


weight=weight-4; //遇见右括号 把权值减去4


p->weight=0;


break;


case '|':


p->weight=weight+1;


break;


case '&':


p->weight=weight+2;


break;


case '~':


p->weight=weight+3;


break;


default:


p->weight=0; //imply the data is char


break;


}


p++;


length++;


}


return length;


}




//查找表达式中权值最小的,作为子树的根节点


int findMin(express *originalexpression,int start,int end)




...{


int key=0;


int current=start;


int location=0;


while(!originalexpression[current].weight)




...{key=originalexpression[current].weight;current++;}


key=current>end?key:originalexpression[current].weight;


location=current>end?0:current;


while(current<=end)




...{


if(originalexpression[current].weight&&originalexpression[current].weight<key)




...{


location=current;


key=originalexpression[current].weight;


}


current++;


}


return location;


}






//分析原表达式,提取所有变量 就是把所有变量罗列在一个数组内


int makeSymbolReprentArray(express *originalexpression)




...{


int length=0;




int hashmap[26]=...{0};


while(originalexpression->data!=10)




...{


if(originalexpression->data>=65&&originalexpression->data<=90)




...{


if(!hashmap[(int)(originalexpression->data-65)])




...{


hashmap[(int)(originalexpression->data-65)]=1;


symbolrepresent[length].data=originalexpression->data;


length++;


}


}


originalexpression++;


}


return length;


}




//查找每个变量所代表值 0或1


int findSymbolRepresent(char symbol)




...{


int location=0;


while(symbolrepresent[location].data!=symbol)




...{


location++;


}


return symbolrepresent[location].weight;


}




//虚拟构建一个二叉树 注意并没有真正构建 不过可理解为建立一个树了 算法核心是一个类似中序遍历二叉树


int virtualCreateTree(express *originalexpression,int start,int end) //在以start和end的范围内建子树




...{


int key=0;


if(start==end) //start==end 表明这个是叶子节点 那么里面是个变量


return findSymbolRepresent(originalexpression[start].data);


else if(start>end)


return 1; //start>end 处理~的特殊情况


else




...{


key=findMin(originalexpression,start,end); //寻找最小权值 作为子树根节点


switch(originalexpression[key].data)




...{


case '|':


return(virtualCreateTree(originalexpression,start,key-1)||virtualCreateTree(originalexpression,key+1,end));


break;


case '&':


return(virtualCreateTree(originalexpression,start,key-1)&&virtualCreateTree(originalexpression,key+1,end));


break;


case '~': //注意~的处理 实际上我是用的(1&&!右子树)


return(virtualCreateTree(originalexpression,start,key-1)&&(!virtualCreateTree(originalexpression,key+1,end)));


}


}





}




//递归给所有变量赋值 注意递归思想用回溯二叉树理解


void recursion(express *symbolrepresent,int i,int length)




...{


if(i<length)




...{


symbolrepresent[i].weight=1; //当前变量取1


recursion(symbolrepresent,i+1,length); //递归调用下一个变量


symbolrepresent[i].weight=0; //当前变量取0


recursion(symbolrepresent,i+1,length); //递归调用下一个变量


}


else //递归结束啦




...{


if(!trueforever||!falseforever) //注意这个处理 当表达式出现可真情况和可假情况 那么断定它是可满足式 没必要做下去了




...{


switch(virtualCreateTree(originalexpression,0,originalexpressionlength-1))




...{


case 1:


trueforever++;


break;


case 0:


falseforever++;


break;


default :


break;


}


}


else


return ;


}


}




//结果处理 没啥说的


void resultReturn(int symbolrepresentlength)




...{


int i=0;


if(trueforever&&falseforever)




...{


printf("您输入的变量名序列为: ");


while(i<symbolrepresentlength)




...{printf("%c ",symbolrepresent[i].data);i++;}


printf(" ");


printf("satisfactible ");


}


else if(!trueforever)


printf("falseforever ");


else


printf("trueforever ");


}




//用户自己设置值 也没啥说的


void userSetWeight()




...{


int i=0;


printf("请依次为变量赋值,并以回车键结束: ");


while(i<symbolrepresentlength)




...{


printf("%c: ",symbolrepresent[i].data);


scanf("%d",&symbolrepresent[i].weight);


i++;


}


if(virtualCreateTree(originalexpression,0,originalexpressionlength-1))


trueforever++;


else


falseforever++;


}




//主目录


void mainFunctionMenus()




...{


int menu=0;


printf("请选择您的变量设值方式: ");


printf("1.计算机自动穷举 ");


printf("2.用户指定设置 ");


scanf("%d",&menu);


if(1==menu)


recursion(symbolrepresent,0,symbolrepresentlength);


else


userSetWeight();


}






int main()




...{


ShowWelcome();


originalexpressionlength = analyse(originalexpression);


symbolrepresentlength = makeSymbolReprentArray(originalexpression);


mainFunctionMenus();


resultReturn(symbolrepresentlength);


//printf("%d",analyse(exp));


//printf(" %d",findMin(exp,0,analyse(exp);))


return 0;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: