您的位置:首页 > 编程语言

重言式判定------参考了别人的代码。。

2011-05-11 17:19 197 查看
【重言式判别】

[
问题描述]

一个逻辑表达式如果对于其变元的任一种取值均为真,则成为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,然而,更多的情况下,既非重言式,也非矛盾式。试写一个程序,通过真值表判别一个逻辑表达式属于上述哪一类。,

[
基本要求]

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











,分别表示或、与和非,运算优先程度递增,但可有括号改变,即括号内的运算优先。逻辑变元为大写字母。表达式中任何地方都可以含有多个空格符。

(2
)若是重言式或矛盾式,可以只显示

True
Forever



False Forever

,否则显示

Satisfactible

以及变量名序列,与用户交互。若用户对表达式变元取定一组值,程序就求出并显示逻辑表达式的值。

[
测试数据]

(1
)(A
|~A
)&(B|~B


(2
)(A&
~A
)&C

(3
)A|B|C|D|E
|~A

[
实现提示]

(1)
识别逻辑表达式的符号形式并建立二叉树可以有两种策略:自底向上的算符优先法和自顶向下分割,先序遍历建立二叉树的方法。

(2)
可设表达式中逻辑变量数不超过20
。真值的产生可以通过在一维数组上维护一个

软计数器

实现,用递归算法实现更简单。
#include<iostream>
using namespace std;
struct Arr
{
char letter;
int weight;
};
class Cys
{
public:
Cys();
void GetTautology();//输入表达式
int _CreateT(int ,int );//虚拟创建二叉树
int FindMin(int ,int );//找到weight最小的
int count();  //计算可满足式的值
void _recursion(Arr *_arr,int i );//递归,穷举
void recursion();//使用接口函数
void Print();//输出结果
~Cys();//析构释放空间
private:
int num;
Arr *array;
Arr _arr[20]; //存放字母
int _arrNum;
int trueforever;
int falseforever;
};

Cys::Cys()
{
trueforever=0;
falseforever=0;
array=new Arr[20];
for(int i=0;i<20;i++){
array[i].weight-1;
array[i].letter='0';
}
_arrNum=0;
num=0;
}
void Cys::GetTautology()
{
int has[27]={0};
int weight=0;
char ch;
cout<<"请输入一个逻辑表达式,以#结束"<<endl;
while(cin>>ch  && ch!='#')
{

if(ch==' ')
continue;

switch(ch)
{
case '(':
weight+=4;
break;
case ')':
weight-=4;
break;
case '&':
array[num].letter=ch;
array[num++].weight=weight+2;
break;
case '|':
array[num].letter=ch;
array[num++].weight=weight+1;
break;
case '~':
array[num].letter=ch;
array[num++].weight=weight+3;
break;
default:
array[num].letter=ch;
if(!has[array[num].letter-'A']){
_arr[_arrNum++].letter=array[num].letter;
has[array[num].letter-'A']=1;
}
array[num++].weight=0;
break;
}

}
}
int Cys:: FindMin(int low,int high)
{
int min=low;
while(!array[min].weight)
min++;

if(min<high){
for(int i=min;i<high+1;i++)
if(array[i].weight && array[i].weight<array[min].weight)
min=i;
return min;
}
else
return 0;

}

int Cys::_CreateT(int low,int high)
{
int Min=0;
// cout<<"create"<<endl;
if(low>high)
return 1;
else if(low==high)
{
// cout<<"letter"<<array[low].letter<<endl;
int i;
for(i=0;_arr[i].letter!=array[low].letter;i++);//从array[]中寻找与_arr[]中相同的字母
return _arr[i].weight;//返回它的weight(1或0)
}
else{
Min=FindMin(low,high);
//cout<<"array[Min].letter: "<<array[Min].letter;
switch(array[Min].letter){
case '&': return( _CreateT(low,Min-1)&& _CreateT(Min+1,high));
break;
case '|': return( _CreateT(low,Min-1)|| _CreateT(Min+1,high));
break;
case '~': return(!_CreateT(Min+1,high));
break;
}
}
}
int Cys:: count() //计算可满足式的值
{
int i=0;
cout<<"请给字母赋值"<<endl;
while(_arrNum--){
cout<<_arr[i].letter;
cin>>_arr[i++].weight;
}
if(_CreateT(0,num-1))
trueforever++;
else
falseforever++;

}

void Cys::_recursion(Arr _arr[],int i)//递归调用
{
if(i<_arrNum){
_arr[i].weight=0;
// cout<<"0"<<endl;
_recursion(_arr,i+1);
_arr[i].weight=1;
// cout<<"1"<<endl;
_recursion(_arr,i+1);
}
else
if(!trueforever||!falseforever)
{
switch(_CreateT(0,num-1))
{
case 1:
// cout<<"trueforever++;"<<endl;
trueforever++;
break;
case 0:
// cout<<"falseforever++;"<<endl;
falseforever++;
break;
default :
break;
}
}
}

void Cys::Print()
{  if(trueforever && falseforever)//如果真假同时存在就判断它为 satisfactible.
cout<<"satisfactible."<<endl;
else if(!trueforever)
cout<<"falseforever."<<endl;
else
cout<<"trueforever. "<<endl;
}

void Cys::recursion()
{
_recursion(_arr,0);
}

Cys::~Cys()
{
delete[] array;
}

int main()
{
cout<<"-------------------重言式判别--------------------"<<endl;
Cys cys;
char c;
cys.GetTautology();
cout<<"计算机穷举请按't' or 用户赋值请按'n'"<<endl;
cin>>c;
if(c=='t')
cys.recursion();//穷举
else
cys.count();//赋值
cys.Print();
system("pause");
return 0;
}


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