离散数学-产生主析取与主合取范式程序代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
产生主析取与主合取范式
测试结果:
输入a&b|c
输出结果
代码:
//离散程序2- 产生主析取范式和主合取范式
#include<stdio.h>
#include<string.h>
char s[100],res[100],stc[100],b[26]; //s为公式;res记录后缀表达式;stc为栈;
int a[26],c[100],top=0,len,r=0,ss[50]; //a纪录字母是否出现, c记录0,1; len代表公式的长度,r为后缀表达式长度
int f(char cc,char ccc) // 验证字母与操作之间是否正确{
if( !(cc==')'||cc=='('||cc=='~'||cc=='!'||cc=='&'||cc=='|'||
(cc<='z'&&cc>='a') ) )return 0;
if( !(ccc==')'||ccc=='('||ccc=='~'||ccc=='!'||ccc=='&'||ccc=='|'|| (ccc<='z'&&ccc>='a') ) )return 0;
if( (cc<='z'&&cc>='a') && (ccc=='!'||ccc<='z'&&ccc>='a') )return 0;
if( (cc=='(' )&& (ccc==')'||ccc=='~'||ccc=='&'||ccc=='|') )return 0;
if( (cc==')')&&(ccc=='!'||ccc<='z'&&ccc>='a') ) return 0;
if( (cc=='~'||cc=='!'||cc=='&'||cc=='|')&&(ccc=='~'||ccc=='&'||ccc=='|' ||ccc==')') ) return 0;
return 1;
}
int push(char cc) //压栈
{
stc[top++]=cc;
}
char pop() //出栈
{
return stc[--top];
}
int compare(char cc,char ccc)
{ // printf("*");
if(cc=='!'&&(ccc=='&'||ccc=='|'||ccc=='~')) return 1;
else if(cc=='&'&&(ccc=='|'||ccc=='~') )return 1;
else if(cc==ccc)return 1;
else if( (cc=='~'&&ccc=='|')||(cc=='|'&&ccc=='~') )return 1;
else return 0;
}
void solve() //求逆波兰式
{
int i;char cc;
for(i=0;i<len;i++)
{ //printf("*");
if(s[i]<='z'&&s[i]>='a')
res[r++]=s[i];
else
{
switch(s[i])
{
case '(': push(s[i]);break;
case ')': cc=pop();
while(cc!='(')
{
res[r++]=cc;cc=pop();
}
break;
default: while( top>=1&&compare(stc[top-1],s[i]) )
{
res[r++]=stc[--top];
}
push(s[i]);
}
}
}
for(i=top-1;i>=0;i--)
res[r++]=stc[i];
res[r]='\0';
// printf("逆波兰式:%s\n",res);
}
int f1(int i) //求!
if(i==1)return 0;
else return 1;
}
int f2(int i,int j) //求|
{
return i>j?i:j;
}
int f3(int i,int j) //求& {
return i*j;
}
int f4(int i,int j) //求~
{
if(i==0)return 1;
else if(i==1&&j==1)return 1;
else return 0;
}
int main()
int i,j,flag,rr=0,h=0,hh=0,len2=0; // flag代表公式是否正确
printf("公式中字母请用小写,或用|,和用&,非用!,蕴含联结词->用~,空格不允许:如p|q&(r~q)\n");
while(1)
{
printf("请输入公式:\n");
gets(s);
len=strlen(s);
flag=0;
int aa=0; // 验证括号是否匹配
for(i=0;i<len;i++)
{
if(s[i]=='(')aa++;
if(s[i]==')')aa--;
if(aa<0){flag=1;break;}
}
if(aa!=0)flag=1;
if(flag){printf("输入公式有错误,需重输\n");continue;}
for(i=0;i<len-1;i++) // 验证字母与操作之间是否正确
if( !f(s[i],s[i+1]) )
{flag=1;break;}
if( !(s[0]<='z'&&s[0]>='a' ||s[0]=='!' ||s[0]=='(') )flag=1;
if(!(s[i]<='z'&&s[i]>='a'||s[i]==')') )flag=1;
if(flag){printf("输入公式有错误,需重输\n");continue;}
int k=0; // k记录字母总数
for(i=0;i<len;i++)
if(s[i]<='z'&&s[i]>='a'&&a[s[i]-'a']==0)
{
a[s[i]-'a']=++k;
b[k]=s[i];
}
solve();
printf("主析取范式:\n");
//求主析取范式
len2=strlen(res);
h=0;
while(!c[k+1])
{
rr=0;
for(i=0;i<len2;i++)
if( !(res[i]>='a'&&res[i]<='z') )
{
if(res[i]=='!')ss[rr-1]=f1(ss[rr-1]);
if(res[i]=='|'){ss[rr-2]=f2(ss[rr-2],ss[rr-1]);rr--;}
if(res[i]=='&'){ss[rr-2]=f3(ss[rr-2],ss[rr-1]);rr--;}
if(res[i]=='~'){ss[rr-2]=f4(ss[rr-2],ss[rr-1]);rr--;}
}
else ss[rr++]=c[a[res[i]-'a']];
hh=0;
if(ss[0])
{
if(h)printf("∨");
printf("(");
for(i=1;i<=k;i++)
{
if(hh)printf("∧");
if(c[a[b[i]-'a']]==0)printf("﹁%c",b[i]);
else printf("%c",b[i]);
hh++;
}
printf(")");
h++;
}
c[1]++;
for(i=1;i<=k;i++)
if(c[i]>1)
{
c[i]=0;
c[i+1]++;
}
}
printf("\n");
printf("主合取范式:\n"); //求
主合取范式
for(i=1;i<=k+1;i++)c[i]=0;
h=0;
while(!c[k+1])
{
rr=0;
for(i=0;i<len2;i++)
if( !(res[i]>='a'&&res[i]<='z') )
{
if(res[i]=='!')ss[rr-1]=f1(ss[rr-1]);
if(res[i]=='|'){ss[rr-2]=f2(ss[rr-2],ss[rr-1]);rr--;}
if(res[i]=='&'){ss[rr-2]=f3(ss[rr-2],ss[rr-1]);rr--;}
if(res[i]=='~'){ss[rr-2]=f4(ss[rr-2],ss[rr-1]);rr--;}
}
else ss[rr++]=c[a[res[i]-'a']];
hh=0;
if(!ss[0])
{
if(h)printf("∧");
printf("(");
for(i=1;i<=k;i++)
{
if(hh)printf("∨");
if(c[a[b[i]-'a']]==0)printf("%c",b[i]);
else printf("﹁%c",b[i]);
hh++;
}
printf(")");
h++;
}
c[1]++;
for(i=1;i<=k;i++)
if(c[i]>1)
{
c[i]=0;
c[i+1]++;
}
}
printf("\n");
for(i=1;i<=k+1;i++)c[i]=0;
for(i=0;i<=25;i++){a[i]=0;b[i]=0;}
top=0;r=0;
printf("\n");
// if(!flag)printf("yes\n");
}
return 0;
}。