⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 源代码.txt

📁 控制台下输入一个数理逻辑表达式
💻 TXT
字号:
// 合析析合.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream"
#include "cstring"
#include "stack"
#include "cmath"
#define maxsize 100
using namespace std;
char str[100];//输入的表达式
int  zhipai[20]={0};//用于指派真值的数组
int length;//逻辑表达式长度
char expression[100];//用于计算的数组
class symbol {
public:
	void solve();
	void Clear(){}
private:
	void change();	
	int Calculate();
	void check();
	bool Get2Operands(double &left,double &right);
	void DoOperator(char op);
	stack<int> s;        //运算栈
};
bool symbol ::Get2Operands(double &left,double &right){   //取两运算值           
	if(s.size()==0){
		cerr<<"Miss Operand!"<<endl;
		return false;
	}
	right=s.top();
	s.pop();
	if(s.size()==0){
		cerr<<"Miss Operand!"<<endl;
		return false;
	}
	left=s.top();
	s.pop();
	return true;
}
void symbol ::DoOperator(char op){   //单次运算                     
	double left,right;
	bool result=Get2Operands(left,right);
	if(result)
		switch(op){
		case '|':s.push(left||right);break;//或运算
		case '&':s.push(left&&right);break;//与运算
		case '>':s.push(!left||right);break;//蕴涵运算
		case '!':s.push((!right)&&left);break;//非运算
		case '=':s.push(left==right);break;//等价运算
		}
	else
		Clear();
}
void symbol ::change()  //将输入的字符串转化为可计算的表达式 
{
	int k=0;                             
	int flag=1;                         
	int count=0; //命题变元个数                       
	for(int i=0;i<pow(2,count);i++)
	{
		k=1;
		for(int m=0;m<length;m++)
		{
			if(isalpha(str[m]))//将原来的命题变元修改为真值
			{
				if(flag==1)
				{
				if(zhipai[k]==0)
					expression[m]='0';
				else
					expression[m]='1';
				k++;
				}
				else
					expression[m]='0';
				flag=1;
				for(int t=m;t>=0;t--)
				{

					if((str[m+1]==str[t])&&isalpha(str[m+1])&&isalpha(str[t]))
						flag=0;
				}
			}
			else
				expression[m]=str[m];//逻辑联结词不变
		}
		for(int t=0;t<length;t++)
		{
			for(int j=t;j<length;j++)
			{
					if(str[t]==str[j])
					{
						expression[j]=expression[t];//相同的命题变元复制赋值
					}
				}
		}
	}
}
void plus(int a[],int q)//二进制加法器,用于指派真值
{
	a[q]=a[q]+1;
	for(int i=q;a[i]==2;i--)
	{	
		a[i]=0;
		a[i-1]=a[i-1]+1;
	}
}
int isp(char ch){     //联结词的栈内优先级
	switch(ch){
	case '#':return 0;break;
	case '(':return 1;break;
	case '!':return 10;break;
	case '=':return 9;break;
	case '&':return 7;break;
	case '|':return 5;break;
	case '>':return 3;break;
	case ')':return 12;break;
	default:return -1;break;
	}
}
int icp(char ch){     //联结词的栈外优先级
	switch(ch){
	case '#':return 0;break;
	case '(':return 12;break;
	case '!':return 11;break;
	case '=':return 8;break;
	case '&':return 6;break;
	case '|':return 4;break;
	case '>':return 2;break;
	case ')':return 1;break;
	default:return -1;break;
	}
}
int symbol ::Calculate(){  //模仿实数加法器进行表达式计算                     
	stack<char> h;
	char ch,y;
	h.push('#');
	for(int temp=0;temp<length-1;temp++)
	{
		ch=expression[temp];
		if(isdigit(ch))//命题变元真值入栈
		{
			if(ch=='0')
			s.push(0);
			else
				s.push(1);
		}
		else if(ch==')')//运算括号内的
		{
			for(y=h.top(),h.pop();y!='(';y=h.top(),h.pop()){
				DoOperator(y);}
		}
		else{
			if(ch=='!')//非运算,在!前加1,将!视作双目操作符
			{
				s.push(1);
			}
			for(y=h.top(),h.pop();isp(y)>icp(ch);y=h.top(),h.pop())
				DoOperator(y);
			h.push(y);
			h.push(ch);
		}
	}
	while(h.size()!=1){
		y=h.top();
		h.pop();
		DoOperator(y);	
	}
	cout <<s.top()<<endl;//输出最终结果
	return s.top();
}
void symbol::check();//检查函数的预先声明
void symbol::solve()//问题的解决
{
	cout<<"请输入命题逻辑表达式(命题变元在a~z中选取,变元个数不要超过20个,或运算用|,与运算用&,非运算用!,蕴涵运算用>,等价运算用=,)以#结尾:"<<endl;
	int flag=1;//标记,防止重复添加命题变元                    
	int count=0;//命题变元的数目                     
	cin >>str;  //输入命题逻辑表达式
	length=strlen(str);	
	char bianyuan[100]; //命题变元数组                               
	for(int i=0;i<length;i++)//逐次添加命题变元
	{
		if(isalpha(str[i])&&(flag==1))
		{
			bianyuan[count]=str[i];count++;
		}
		flag=1;
		for(int k=0;k<count;k++)
		{
			if(bianyuan[k]==str[i+1])flag=0;
		}		
	}    
	if(count==0)
	{cout<<"无命题变元,重新输入!"<<endl;solve();}
	cout<<"真值表(用0代替false,用1代替true):" <<endl;
	check();//合法性检查
	for(int w=0;w<count;w++)
		cout<<bianyuan[w]<<' ';
	cout<<"fc"<<endl;
	int* truth=new int[pow(2,count)];
	stack<char> xh1;
	xh1.push('(');
	stack<char> xh2;
	stack<char> hx1;
	hx1.push('(');
	stack<char> hx2;
	for(int r=0;r<pow(2,count);r++)//输出真值表
	{
		for(int j=1;j<=count;j++)
		{cout<<zhipai[j]<<' ';}
		change(); 
	    truth[r]=Calculate(); 
		if(truth[r]==1)  //成真指派入析合栈   
		{
			for(int t=0;t<count;t++)
			{
				if(zhipai[t+1]==1)
				{
					xh1.push(bianyuan[t]);
					xh1.push('&');
				}
				else
				{
					xh1.push('!');
					xh1.push(bianyuan[t]);
					xh1.push('&');
				}
			}
			xh1.pop();
			xh1.push(')');
			xh1.push('|');
			xh1.push('(');
		}
		if(truth[r]==0)   //成假指派入合析栈               
		{
			for(int c=0;c<count;c++)
			{
				if(zhipai[c+1]==1)
				{
					hx1.push(bianyuan[c]);
					hx1.push('|');
				}
				else
				{
					hx1.push('!');
					hx1.push(bianyuan[c]);
					hx1.push('|');
				}
			}
			hx1.pop();
			hx1.push(')');
			hx1.push('&');
			hx1.push('(');
		}
		plus(zhipai,count);
	}
	//析合范式与合析范式的输出
	cout<<"析合范式为:";
	if(xh1.size()==1)
		cout<<"无析合范式,此表达式为矛盾式";
	else{
		xh1.pop();//弹出'('
		xh1.pop();//弹出'|'
		while(xh1.size()!=0)
		{
			xh2.push(xh1.top());
			xh1.pop();
		}
		while(xh2.size()!=0)
		{
			cout<<xh2.top();
			xh2.pop();
		}
	}
	cout<<endl;
	cout<<"合析范式为:";
	if(hx1.size()==1)
		cout<<"无合析范式,此表达式为重言式";
	else{
		hx1.pop();//弹出'('
		hx1.pop();//弹出'&'
		while(hx1.size()!=0)
		{
			hx2.push(hx1.top());
			hx1.pop();
		}
		while(hx2.size()!=0)
		{
			cout<<hx2.top();
			hx2.pop();
		}
	}
	cout<<endl;	
	cout<<"是否继续运算?Y/N"<<endl;
	char goon;
	cin>>goon;
	if(goon=='y'||goon=='Y')
		solve();//递归调用solve,重新计算
	else{
		cout<<"作者:"<<endl;
		cout<<"061221009 陈阳"<<endl;
		cout<<"Computer Science NJU"<<endl;
		cout<<":p"<<endl;
		exit(-1);
	}

}
void symbol::check()//检查输入的逻辑表达式是否合法(只对部分语法做检查)
{
	if(str[length-1]!='#'){cout<<"未以#结尾,重新输入!"<<endl;solve();}
	if(!isalpha(str[length-2])&&str[length-2]!=')'){cout<<"错误,重新输入!"<<endl;solve();}
	for(int i=0;i<length-1;i++)
	{
		if(!isalpha(str[i])&&str[i]!='&'&&str[i]!='|'&&str[i]!='>'&&str[i]!='='&&str[i]!='!'&&str[i]!='('&&str[i]!=')')
		{
			cout<<"错误的字符,重新输入!"<<endl;solve();
		}
		if(isalpha(str[i])&&isalpha(str[i+1])){cout<<"命题变元之间无联结词,重新输入!"<<endl;solve();}
		if(isalpha(str[i])&&str[i+1]=='('){cout<<"命题变元后不可接(,重新输入!"<<endl;solve();}
		if(!isalpha(str[i])&&!isalpha(str[i+1])&&(str[i]!='('&&str[i+1]!='!')&&str[i+1]!='('&&str[i]!=')')
		{
			cout<<"联结词间无命题变元,重新输入!"<<endl;solve();
		}
	
	}
	int left=0,right=0,j=0;
	while(j<length-1)
	{
		if(str[j]=='(')
			left++;
		if(str[j]==')')
			right++;
		if(right>left)
		{cout<<"括号次序不匹配,重新输入!"<<endl;solve();}
		j++;
	}
	if(left!=right){cout<<"括号个数不匹配,重新输入!"<<endl;solve();}

}
int main()
{
	symbol a;
    a.solve();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -