c++ 复合命题打真值表

第一次写博客,新鲜又紧张,写的不好,大犇轻喷。

实现功能 从文本中读取复合命题,并在文本文件中打印真值表

[如果不清楚文本读取,可以先浏览这个博客](https://www.cnblogs.com/uniqueliu/archive/2011/08/03/2126545.html)
 简单来说就是用ifstream和ofstream实例化一个对象,并将其与你要操作的文本文件绑定;
 ifstream用于从文本里读取数据,它重载了>>;
 ofstream用于创建一个文本文件,并将数据输入到改文本里,它重载了<<。
 
  [这里还用到了栈和后缀表达式,不太清楚的可以参考这个博客](https://blog.csdn.net/PaRzVaL/article/details/105360855?tdsourcetag=s_pctim_aiomsg)

#整体思路

在这里插入图片描述
由于这里需要对数据进行频繁的随机访问,而且只需要在容器的尾端进行删除和添加的操作,所以这里可以直接使用vector或者指针,
下面的代码是以vector为例实现的

这里支持的逻辑连接词包括析取,合取,否定,蕴含和等价连接词
|表示析取,&表示合取,!表示取反,>表示蕴含,=表示等价

#代码

#include<bits/stdc++.h> 
using namespace std;
class Pro
{
    private: 
      vector<char> book_1;            //储存子命题 
	  vector<bool> ans;              //储存后缀表达式 
	  vector<char> pro_2,pro;       //堆栈储存复合命题 
	  bool  book_2[20];            //储存子命题对应的布尔变量 
	  string pro_1;
	  
  	  bool  contain(bool a,bool b);  	//自定义蕴含运算 
	  bool  equ(bool a,bool b);        //自定义等价运算 
      void  star();                   //文本处理工作 
	  void  add();                   //统计子命题及其个数 
	  void  put_out();              //对后缀表达式进行运算
	  void  mind();                //对用户指令进行判断 
	public:
      void slove()
      {
      	star(); 
        add();
        put_out();
	  }
};
void Pro::mind()
{
	   char op;
	   cin>>op;
	   if(op=='Y')
	   {
	   	cin>>pro_1;
	   }
	   else if(op=='N')
	   {
	   	ifstream infile("复合命题.txt");
        getline(infile,pro_1);
	   }
	   else
	   {
	   	cout<<"指令错误,请重新输入指令"<<endl; 
	   	mind();
	   }
}
void Pro::star()
{
	   //此处规定 子命题为小写字母  !为非  &为合取 |为析取  >为蕴含 =为等价 
	   ofstream outfile("复合命题.txt");
	   outfile<<"!(q|p)>!r&m" ;
	   outfile.close();
	   cout<<"!注意 !  此处规定 自命题为小写字母  !为非  &为合取 |为析取  >为蕴含 =为等价  " <<endl<<endl; 
	   cout<<"目前计算的是: p|!q>r|((!p&!r>q)>r&(q|p&!r)>p|!q>r|)(!p&!r>q)>r&(q|p&!r) 的真值表"<<endl;
	   cout<<"如果你要自己输入一个复合命题打表 请输入Y 否则输入N"<<endl; 
    
       mind();     //判断选择 
       
       pro_2.push_back('0');
       int i,j,w;  
	   vector<int> a; 
	   for(i=0;i<pro_1.size();i++) 
       {
       	    //遇到子命题输出  注意运算符的优先级 
       	    if(pro_1[i]>='a'&&pro_1[i]<='z')
		    pro.push_back(pro_1[i]);
		    else if(pro_1[i]==')')
		    {
		   	  while(1)
       	     {
       	     	if(pro_2.back()=='(')
       	     	{
       	     	a.pop_back();	
				pro_2.pop_back();
				break;
			    }	
				pro.push_back(pro_2.back());
				pro_2.pop_back();
				a.pop_back();
		      }
	         }
	         else if(pro_1[i]=='('||pro_1[i]=='!'||pro_1[i]=='&'||pro_1[i]=='|'||pro_1[i]=='>'||pro_1[i]=='=')
			 {
			 	switch(pro_1[i])
			    {
			     case '(':   j=6;         break;
			     case '!':   j=5;         break;
			     case '&':   j=4;         break;
			     case '|':   j=3;         break;
			     case '>':   j=2;         break;
			     case '=':   j=1;         break;
		         }
		         
		         //识别到的运算符合栈顶运算符比较优先级 
		         //小于或等于栈顶符号优先级的话,把栈顶运算符输入,再次比较新栈顶运算符 
		         if(a.size())
		         {
		         	while(j<=a.back()&&a.back()!=6)
		         	{
					pro.push_back(pro_2.back());
			        pro_2.pop_back();
			        a.pop_back();
			        if(!a.size())
			        break;
			        }
				 }
				 a.push_back(j);
				 pro_2.push_back(pro_1[i]);
			  } 
      }
           //把所有运算符出栈 
           while(pro_2.size()&&pro_2.back()!='0')
           pro.push_back(pro_2[pro_2.size()-1]),pro_2.pop_back(); 
           
}
bool Pro::contain(bool a,bool b)
{
	if(a==1&&b==0)
	return 0;
	else
	return 1;
} 
bool Pro::equ(bool a,bool b)
{
	if((a==1&&b==1)||(a==0&&b==0))
	return 1;
	else
	return 0;
} 
void Pro::add()
{
	 	int i,j,k;
	 	bool o=0;
	 	//此处遍历是为了记录共有几个子命题,为赋值做准备 
	 	for(i=0;i<pro.size();i++)
	 	{
	 		if(pro[i]>='a'&&pro[i]<='z')
	 		{
	 			for(j=0;j<book_1.size();j++)
	 			{
	 			  if(pro[i]==book_1[j])
				   {
				   	o=1;
				   	break;
					}	
			    }
				 
				 if(o==1)
				 {
				 	o=0;
				 	continue;
				 }
				 else
				 book_1.push_back(pro[i]); 
			 }
		}		
}
void Pro::put_out()
{	
	 	int i,j,k,l,sum;
	 	bool a,b;
	 	int di,dv;
	 	ofstream myfile("answer.txt");
	 	
	 	//此处依次为子命题赋值,并遍历每一种情况 
	    for(sum=0;sum<pow(2,book_1.size());sum++)	
	    { 
	    if(sum==0)
	    {
	    	for(i=0;i<book_1.size();i++)
	    	{
			myfile<<book_1[i]<<"  ";
	    	cout<<book_1[i]<<"  ";
	        }
	    	myfile<<"answer"<<endl;	
	    	cout<<"answer"<<endl;	
		}
	 	di=sum;
	 	for(i=0;i<book_1.size();i++)
	 	{
	 		dv=di%2;
	 		di/=2;
	 		if(dv)
	 		book_2[i]=1;
	 		else
	 		book_2[i]=0;
	 		cout<<book_2[i]<<"  ";
	 		myfile<<book_2[i]<<"  ";
		 } 
         
         //开始计算 
	 	 	for(k=0;k<pro.size();k++)
		  { 
		  	//子命题入栈 
		  	if(pro[k]>='a'&&pro[k]<='z')
		  	{
		  		for(l=0;l<book_1.size();l++)
		  		{
		  			if(book_1[l]==pro[k])
		  			{
		  				ans.push_back(book_2[l]);
		  				break;
					  }
				  }
			}
			//运算符出栈 
			if(pro[k]=='&'||pro[k]=='|'||pro[k]=='>'||pro[k]=='=')
			{
			a=ans.back();
		  	ans.pop_back();
		  	b=ans.back();
		  	ans.pop_back();
			 switch(pro[k])
			 {
			 case '&':  ans.push_back(a&b);	        break;
			 case '|':  ans.push_back(a|b);	        break;
			 case '>':  ans.push_back(contain(b,a)); break;
			 case '=':  ans.push_back(equ(b,a));    break;
		     }
		    }
			if(pro[k]=='!')
			{	
				a=ans.back();
				ans.pop_back();
				ans.push_back(!a); 
			}
		  }
		  cout<<"  "<<ans.back()<<endl;
		  myfile<<"  "<<ans.back()<<endl;
		  ans.pop_back();	  
	    }
	     cout<<"完成打表"; 
	     myfile.close();
}
int main()
{
	Pro test_1;
	test_1.slove();
    
    return 0;
 } 

结果
在这里插入图片描述

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值