📄 源代码.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 + -