p 0等价的c语言表达式是,离散数学:验证P,Q两个逻辑表达式是否逻辑等价(C语言实现)...

一、程序通过编译,并实现两个命题的各种逻辑运算

二、任意输入字符串P和Q逻辑表达式的合法性检查

三、利用真值表方法验证他们的等价性

一、算法分析

①    求任意一个命题公式的真值表,,根据真值表验证他们的等价性

C语言算法:

首先是输入一个合理的式子,然后从式子中查找出变量的个数,开辟一个二进制函数,用来生成真值表,然后用函数运算,输出结果,并根据结果归类给范式,再根据范式验证等价性。

函数部分,主要是3个函数,一个为真值表递加函数,通过二进制的加法原理递进产生,一个为分级运算函数,这个函数是通过判断括号,选出最内级括号的内容执行运算函数,这样一级一级向外运算,最后得出最终结果,剩下一个为主运算函数,按照运算符号的优先级按顺序进行运算,如先将所有非运算运算完,再执行与运算。如此运算。

/**主运算函数**/

intMAP(char sz[N],char ccu[N],int icu[N],int h0)

{

int i, h = 0, j = 0, j1 = 0, j2 = 0, j3 = 0,j4 = 0, j5 = 0, i1, i2, p1 = -1, p2 = -1, s;

char dt[N];

s = strlen(sz);

if(s == 1)

if(sz[0] == -2) //判断是否是最后一项

return0;

else

return1; //1就是sz[0]的值、

else{

for(i = 0; i < s-j; i++) //先处理非

if(sz[i]== '!'){

for(i1 = 0; i1 < h0; i1++)

if(sz[i+1]== ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == -2)//如果是前运算结果的0,则P1等于0

p1= 0;

if(p1 == -1)//如果是数字,直接给P1

p1= sz[i+1];

dt[j+2] = !p1;//非运算

sz[i] = j+2;

j++;

p1 = 0;

for(i1 = i+1; i1 < s-j; i1++)

sz[i1]= sz[i1+1];//将后续式子前移一项

}

p1= -1;

j1= j;

for(i = 0; i < s-j1-2*j2; i++) // 处理与

if(sz[i]== '&'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1]== ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1]== ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1) //如果是数字,直接给P1

p1 = (int)(sz[i-1]);

if(p2 ==-1)//如果是数字,直接给P2

p2 = (int)(sz[i+1]);

dt[j+2] = p1 && p2;//与运算

sz[i-1] = j+2;

j++;

j2++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2; i1++)//将后续式子前移两项

sz[i1] = sz[i1+2];

i = i-1;

}

for(i = 0; i < s-j1-2*j2-2*j3; i++) // 处理或。

if(sz[i] == '|'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2=2;i2

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2)//如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i-1];

if(p2 == -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2] = p1 || p2;//或运算

sz[i-1] = j+2;

j++;

j3++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2-2*j3;i1++)//将后续式子前移两项

sz[i1]=sz[i1+2];

i--;

}

for(i = 0; i < s-j1-2*j2-2*j3-2*j4;i++) // 处理蕴含。

if(sz[i] == '^'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1]== -2)//如果是前运算结果的0,则P1等于0

p1 =0;

if(sz[i+1]== -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1== -1)//如果是数字,直接给P1

p1 =sz[i-1];

if(p2== -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2]= (!p1) || p2;//蕴含运算

sz[i-1]= j+2;

j++;

j4++;

p1= -1;

p2= -1;

for(i1= i; i1 < s-j1-2*j2-2*j3-2*j4; i1++)//将后续式子前移两项

sz[i1] = sz[i1+2];

i--;

}

for(i = 0; i < s-j1-2*j2-2*j3-2*j4-2*j5; i++) // 处理等值。

if(sz[i] == '~'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i-1];

if(p2 == -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2] = (!p1 || p2) && (!p2|| p1);//等值运算

sz[i-1] = j+2;

j++;

j5++;

p1 = -1;

p2 = -1;

for(i1 = i; i1

sz[i1] = sz[i1+2];

i--;

}

return dt[j+1];//返回结果

}

}

/**分级运算函数**/

intCR(char sz[N],char ccu[N],int icu[N],int h0)

{

int i,j,h,s,kh = 0,wz[N],a;

char xs1[N],ckh[N]; //xs1用来保存括号内的字符 ckh用来保存括号。

s= strlen(sz);

for(i = 0; i < s; i++)

if(sz[i] == '(' || sz[i] == ')'){ //判断括号

wz[kh]= i; //存储括号位置

ckh[kh]= sz[i]; //存储括号类型

kh++;

}

if(kh == 0)

returnMAP(sz,ccu,icu,h0); //如果无括号,直接运行

else{

for(i= 0; i < kh; i++)

if(ckh[i] == ')') //找到第一个" )"

break;

for(j= wz[i-1]+1,h=0; j < wz[i]; j++,h++) //存储最内级括号中的内容

xs1[h] = sz[j];

xs1[h]= '\0';

a= MAP(xs1,ccu,icu,h0); //运行最内级括号的式子,得到结果

if(a== 1) //判断并存储结果

sz[wz[i-1]] = 1;

else

sz[wz[i-1]] = -2;

for(j= wz[i-1]+1; j < s+wz[i-1] - wz[i]; j++)//将括号后内容前移

sz[j] = sz[j + wz[i] - wz[i-1]];

sz[j]= '\0';

returnCR(sz,ccu,icu,h0);//循环执行

}

}

/**二进制赋值函数**/

voidBVA(int b[N],int f){

int i;

i= f;

if(b[f] == 0) //加1

b[f]= 1;

else //进位

{

b[f]= 0;

BVA(b,--i);

}

}

/**根据范式判断两个逻辑表达式是否等价**/

for(i1 = 0;i1 < h; i1++){

hq1[j] = hq[i1];

}

for(i1 = 0;i1 < h; i1++){

hq2[j] = hq[i1];

}

for(i1 = 0;i1 < h; i1++){//判断两个逻辑表达式是否等价

if(hq1[i1] != hq2[i1]){

flag = 0;

break;

}

else

flag = 1;

}

if(flag ==0)printf("\t\t# 您输入的两个逻辑表达式不等价 #\n");

else if(flag ==1)printf("\t\t# 您输入的两个逻辑表达式等价 #\n");

程序运行界面如下:

c24a3400e3bdd2c1a514c57d894892dc.png

b8cf3407042e468eccc6d4ed2fe72e2c.png

691e09c6db4a55aa84b312376925355d.png

633a668f2143a54acfadd3bbd5fd8a06.png

程序清单

#include

#include

#include

#include

#include

#define N 50

int hq[N],i1,h=0;//定义全局变量

/**主运算函数**/

int MAP(char sz[N],char ccu[N],int icu[N],int h0)

{

int i, h = 0, j = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, i1, i2, p1 = -1, p2 = -1, s;

char dt[N];

s = strlen(sz);

if(s == 1)

if(sz[0] == -2)//判断是否是最后一项

return 0;

else

return 1;//1 就是sz[0]的值、

else{

for(i = 0; i < s-j; i++) //先处理非

if(sz[i] == '!'){

for(i1 = 0; i1 < h0; i1++)

if(sz[i+1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i+1];

dt[j+2] = !p1;//非运算

sz[i] = j+2;

j++;

p1 = 0;

for(i1 = i+1; i1 < s-j; i1++)

sz[i1] = sz[i1+1];//将后续式子前移一项

}

p1 = -1;

j1 = j;

for(i = 0; i < s-j1-2*j2; i++) // 处理与

if(sz[i] == '&'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1) //如果是数字,直接给P1

p1 = (int)(sz[i-1]);

if(p2 ==-1)//如果是数字,直接给P2

p2 = (int)(sz[i+1]);

dt[j+2] = p1 && p2;//与运算

sz[i-1] = j+2;

j++;

j2++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2; i1++)//将后续式子前移两项

sz[i1] = sz[i1+2];

i = i-1;

}

for(i = 0; i < s-j1-2*j2-2*j3; i++) // 处理或。

if(sz[i] == '|'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2=2;i2

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2)//如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i-1];

if(p2 == -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2] = p1 || p2;//或运算

sz[i-1] = j+2;

j++;

j3++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2-2*j3; i1++)//将后续式子前移两项

sz[i1]=sz[i1+2];

i--;

}

for(i = 0; i < s-j1-2*j2-2*j3-2*j4; i++) // 处理蕴含。

if(sz[i] == '^'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i-1];

if(p2 == -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2] = (!p1) || p2;//蕴含运算

sz[i-1] = j+2;

j++;

j4++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2-2*j3-2*j4; i1++)//将后续式子前移两项

sz[i1] = sz[i1+2];

i--;

}

for(i = 0; i < s-j1-2*j2-2*j3-2*j4-2*j5; i++) // 处理等值。

if(sz[i] == '~'){

for(i1 = 0; i1 < h0; i1++){

if(sz[i-1] == ccu[i1])//将变量赋值并给P1

p1 = icu[i1];

if(sz[i+1] == ccu[i1])//将变量赋值并给P2

p2 = icu[i1];

}

for(i2 = 2; i2 < j+2; i2++) {

if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1

p1 = dt[i2];

if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2

p2 = dt[i2];

}

if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0

p1 = 0;

if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0

p2 = 0;

if(p1 == -1)//如果是数字,直接给P1

p1 = sz[i-1];

if(p2 == -1)//如果是数字,直接给P2

p2 = sz[i+1];

dt[j+2] = (!p1 || p2) && (!p2 || p1);//等值运算

sz[i-1] = j+2;

j++;

j5++;

p1 = -1;

p2 = -1;

for(i1 = i; i1 < s-j1-2*j2-2*j3-2*j4-2*j5; i1++)//将后续式子前移两项

sz[i1] = sz[i1+2];

i--;

}

return dt[j+1];//返回结果

}

}

/**分级运算函数**/

int CR(char sz[N],char ccu[N],int icu[N],int h0)

{

int i,j,h,s,kh = 0,wz[N],a;

char xs1[N],ckh[N];//xs1用来保存括号内的字符 ckh用来保存括号。

s = strlen(sz);

for(i = 0; i < s; i++)

if(sz[i] == '(' || sz[i] == ')'){//判断括号

wz[kh] = i;//存储括号位置

ckh[kh] = sz[i];//存储括号类型

kh++;

}

if(kh == 0)

return MAP(sz,ccu,icu,h0);//如果无括号,直接运行

else{

for(i = 0; i < kh; i++)

if(ckh[i] == ')')//找到第一个" )"

break;

for(j = wz[i-1]+1,h=0; j < wz[i]; j++,h++) //存储最内级括号中的内容

xs1[h] = sz[j];

xs1[h] = '\0';

a = MAP(xs1,ccu,icu,h0);//运行最内级括号的式子,得到结果

if(a == 1)//判断并存储结果

sz[wz[i-1]] = 1;

else

sz[wz[i-1]] = -2;

for(j = wz[i-1]+1; j < s+wz[i-1] - wz[i]; j++)//将括号后内容前移

sz[j] = sz[j + wz[i] - wz[i-1]];

sz[j] = '\0';

return CR(sz,ccu,icu,h0);//循环执行

}

}

/**二进制赋值函数**/

void BVA(int b[N],int f){

int i;

i = f;

if(b[f] == 0) //加1

b[f] = 1;

else//进位

{

b[f] = 0;

BVA(b,--i);

}

}

/**求任意一个命题公式的真值表**/

void Matrice(){

int i2,d=1,icu[N],kh=0,jg,j=0,h0;//icu[N]用于存放变量值,kh括号计数,jg存放结果

int bj=0,x=0,xq[N];//hq[N]存放合取结果xq[N]存放析取结果

char sz[N],ccu[N],sz0[N];//sz[N]存放式子,ccu[N]存放变量,sz0[N]也是用于存放式子

hq[0]=-1;

xq[0]=-1;

printf("\n\t\t*************************************************\n");

printf("\t\t** **\n");

printf("\t\t** (可运算真值表,主范式,支持括号) **\n");

printf("\t\t** **\n");

printf("\t\t** 用!表示非 **\n");

printf("\t\t** 用&表示与 **\n");

printf("\t\t** 用|表示或 **\n");

printf("\t\t** 用^表示蕴含 **\n");

printf("\t\t** 用~表示等值 **\n");

printf("\t\t** **\n");

printf("\t\t*************************************************\n");

sg:printf("\t\t");

gets(sz);

strcpy(sz0,sz);

for(i1 = 0; (size_t)i1 < strlen(sz); i1++){

if(sz[i1] =='!' || sz[i1] == '&' || sz[i1] == '|' || sz[i1] == '^' || sz[i1] == '~' || sz[i1] == '(' || sz[i1] == ')' || sz[i1] >= 'a' && sz[i1] <= 'z' || sz[i1] >= 'A' && sz[i1] <= 'Z'){

if(sz[i1] == ')' || sz[i1] == '(')//存储括号数量

kh++;

if(sz[i1] >= 'a' && sz[i1] <= 'z' || sz[i1] >= 'A' && sz[i1] <= 'Z') {

if(sz[i1+1] >= 'a' && sz[i1+1] <= 'z' || sz[i1+1] >= 'A' && sz[i1+1] <= 'Z'){

printf("\t\t# 您输入的数据不合法!请重新输入!\n");

goto sg;

}

for(i2 = 0; i2 < j; i2++) //判断并储存变量。

if(ccu[i2] == sz[i1])//去除重复变量

d = 0;

if(d == 1){

ccu[j] = sz[i1];

j++;

}

d = 1;

}

}

else{

printf("\t\t# 您输入的数据不合法!请重新输入!\n");

goto sg;

}

}

printf("\n\t\t*************************************************\n");

printf("\n\t\t该命题公式中的变量个数为:%d\n",j);//输出变量个数

h0 = j;

printf("\n\t\t输出真值表如下:\n \n"); //输出真值表表头

printf("\t\t");

for(i1 = 0; i1 < h0; i1++)

printf(" %c ",ccu[i1]);

printf(" ");

printf("\t\t");

puts(sz);

printf("\n");

for(i1 = 0; i1 < j; i1++) ///先将所有的变量赋值为零。

icu[i1] = 0;

printf("\t\t");

for(i2 = 0; i2 < j; i2++)//输出真值表前项

printf(" %d ",icu[i2]);

jg = CR(sz,ccu,icu,h0); //用函数求结果

if(jg == 0)

hq[h++] = bj;

printf("\t\t%d\n",jg);//输出运算结果

strcpy(sz,sz0);

for(i1 = 0; i1 < (int)pow(2,j)-1; i1++){

++bj;

BVA(icu,j-1); //赋值变量

jg = CR(sz,ccu,icu,h0);

if(jg == 0)

hq[h++] = bj;

strcpy(sz,sz0); //恢复被修改的数组。

printf("\t\t");

for(i2 = 0; i2 < j; i2++)

printf(" %d ",icu[i2]);//输出真值表前项

printf("\t\t%d\n",jg);//输出运算结果

}

printf("\n");

}

void Ma_Start(){

int hq1[N],hq2[N],j = 0,flag = 0;

printf("\n\t\t*************************************************\n");

printf("\t\t** **\n");

printf("\t\t# 输入合法的逻辑表达式P #");

getchar();

Matrice();

for(i1 = 0; i1 < h; i1++){

hq1[j] = hq[i1];

}

printf("\t\t# 输入合法的逻辑表达式Q #");

Matrice();

for(i1 = 0; i1 < h; i1++){

hq2[j] = hq[i1];

}

for(i1 = 0; i1 < h; i1++){//判断两个逻辑表达式是否等价

if(hq1[i1] != hq2[i1]){

flag = 0;

break;

}

else

flag = 1;

}

if(flag == 0)printf("\t\t# 您输入的两个逻辑表达式不等价 #\n");

else if(flag == 1)printf("\t\t# 您输入的两个逻辑表达式等价 #\n");

printf("\t\t** **\n");

printf("\t\t*************************************************\n");

printf("\t\t");

}

void Start(){

char s;

printf("\t\t*************************************************\n");

printf("\t\t** **\n");

printf("\t\t** 欢迎使用逻辑运算器 **\n");

printf("\t\t** **\n");

printf("\t\t*************************************************\n");

navi : printf("\n\t\t*************************************************\n");

printf("\t\t** **\n");

printf("\t\t** 您可以选择a或b执行以下操作 **\n");

printf("\t\t** a、测试P,Q两个逻辑表达式是否逻辑等价 **\n");

printf("\t\t** b、退出系统 **\n");

printf("\t\t** **\n");

printf("\t\t*************************************************\n");

printf("\t\t");

scanf("%c",&s);

switch(s){

case 'a' : system("cls");Ma_Start();break;

case 'b' : break;

default : printf("\t\tenter data error!\n");

}

if(s != 'b')

goto navi;

else{ //退出

printf("\t\t*************************************************\n");

printf("\t\t** **\n");

printf("\t\t** 欢迎再次使用!谢谢! **\n");

printf("\t\t** **\n");

printf("\t\t*************************************************\n");

}

}

int main(){

Start();

return 0;

}

总结:求任意一个命题公式的真值表及其主范式就相对较难,解决了求命题公式的真值表及其主范式的问题后,求两逻辑表达式是否等价就变得十分简单,关键在与求一个命题公式的真值表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值