逻辑表达式等价判断

题目要求:

给出两个c语言中的逻辑表达式,判断两个表达式是否完全一样(对变量所有的取值,两个表达式的值一样),表达式中的变量可由字母a-z中的任何一个表示,运算符由'|'(或),'&'(与),'^'(异或),'~'(非)组成,表达式中还可能有圆括号,各运算符的优先级跟c语言一样。
输入每两行一组,分别为两个表达式(长度不大于100).
如果两个表达式一样,则输出Equivalent,否则输出Different
如输入:
a^b&(b|a)
(a^(b&(b|a)))


a ^b&(b|a)
~b^a
输出为:
Equivalent


Different


话不多说,直接上源码:

源程序代码(编译环境Visual C++ 6.0

#include<stdio.h>
#include<string.h>
#include<math.h>
//N为表达式的长度
#define N 105
  
int equal(char a[],char b[],int l1,int l2);//判断两个逻辑表达式是否等价
int getnumber(char a[],int l);//获取变量的个数
char cal(char a[],int l);//计算逻辑表达式的值
int pri(char ch);//判断符号的优先级
  
char c[26];//用来记录表达式中变量的个数以及变量的名称
int main()
{
      char ans1[N],ans2[N];
      int l1,l2;//两个表达式的长度
    printf("请输入两个逻辑表达式\n");
      while(scanf("%s%s",ans1,ans2)!=EOF)
      {
            l1=strlen(ans1);
            l2=strlen(ans2);
            if(equal(ans1,ans2,l1,l2))
              printf("Equivalent\n");
            else
              printf("Different\n");
      }
      return 0;
}
int equal(char a[],char b[],int l1,int l2)
{
      int i,j;
      char zhi1,zhi2;
      char ctemp[26];//分别位a,b,c的临时数组
      char atemp[N];
      char btemp[N];
      int x=0,y=0;//a,b表达式中的变量个数
      int n;//所有取值的种数
      int tempn,max;
      char list[26];//变量取值表
      y=getnumber(b,l2);
    x=getnumber(a,l1);
//   printf("变量个数:%d\n",x);
    max=x>y?x:y;//取两个表达式中变量(以多的为准)
      n=pow(2.0,max);//获取取值的总数,如3个变量有2^3种
//   printf("取值种数:%d\n",n);
      while(n)
      {
        getnumber(a,l1);
            strcpy(ctemp,c);//还原
            strcpy(atemp,a);//还原
       
            tempn=n;
       
            for(i=x;i>=0;i--)//Max位变量取值表
            {           
                  list[i]=tempn%2+'0';
                  tempn/=2;
             
            }
                  j=1;
            for(i=0;i<26;i++)//构建26位取值表
            {
                  if(ctemp[i]!='0')
                  {
                       ctemp[i]=list[j++];
                  }
            }
            for(i=0;i<l1;i++)//将a表达式中的变量换为对应的值!比如a换为0,b换为0
            {
                  if(atemp[i]>='a'&&atemp[i]<='z')
                  atemp[i]=ctemp[atemp[i]-'a'];
            }
  
            strcpy(btemp,b);//还原 
            for(i=0;i<l2;i++)//将b表达式中的变量换为对应的值!比如a换为0,b换为0
            {
                  if(btemp[i]>='a'&&btemp[i]<='z')
                  btemp[i]=ctemp[btemp[i]-'a'];
            }
            zhi1=cal(atemp,l1);//计算结果
            zhi2=cal(btemp,l2);
            if(zhi1!=zhi2)//判断两个表达式值是否相等
            {
                  return 0;
            }
            n--;
      }
       
      return 1;
}
int getnumber(char a[],int l)
{
       
      int number=0;//变量的个数
      int i;
      memset(c,'0',sizeof(c));
      for(i=0;i<l;i++)
      {
            if(a[i]>='a'&&a[i]<='z')
            {
                  c[a[i]-'a']+=1;
            }
      }
      for(i=0;i<26;i++)
      {
            if(c[i]!='0')
            {
                  number++;
            }
      }
      return number;
}
char cal(char a[],int l)
{
      int i;
      int top=0;
      int j=0;
      char stack[N];//利用栈将中序式转为后序式
      char fin[N];//转换后的后序式
      char result[N];//用来保存结果的栈
      char ch;
      fin[0]='#';
      for(i=0;i<=l;i++)
      {
            switch(a[i])
            {
                  case '\0':
                  while(top>0)
                  {
                      fin[++j]=stack[top--];
                  }
                  break;
                   
                  case '(':
                   
                  stack[++top]=a[i];
                  break;
                   
                  case '|':       
                  case '^':
                  case '&':
                  case '~':
                  while(pri(stack[top])>=pri(a[i]))
                  {
                       fin[++j]=stack[top--];
                  }
                  stack[++top]=a[i];
                  break;
                   
                  case ')':
                  while(stack[top]!='(')
                  {
                       fin[++j]=stack[top--];
                  }
                  top--;
                  break;
                   
                  default:
                  fin[++j]=a[i];
                  break;
            }
      }
      fin[++j]='\0';
  
      top=0;
      for(i=1;i<j;i++)
      {
            if(fin[i]=='0'||fin[i]=='1')
            {
                  result[top++]=fin[i];
            }
            else
            {
                  switch(fin[i])
                  {
                       case '~':
                       ch=result[--top];
                   
                  result[top]=(ch=='1')?'0':'1';
  
                       top++;
                       break;
                       case '&':
                       ch=result[--top];   result[top-1]=(ch=='1'&&result[top-1]=='1')?'1':'0';
                       break;
                       case '|':
                                               ch=result[--top];   result[top-1]=(ch=='1'||result[top-1]=='1')?'1':'0';
                       break;
                        
                       case '^':
                                               ch=result[--top];   result[top-1]=(ch==result[top-1])?'0':'1';
                       break;
                       default:
                       printf("error\n");
                       break;
                  }
            }
      }
  
      return result[0];
}
int pri(char ch)
{
      int num;
      switch(ch)
      {
            case '~':
            num=4;
            break;
            case '&':
            num=3;
            break;
            case '^':
            num=2;
            break;
            case '|':
            num=1;
            break;
            default:
            num=0;
            break;
      }
      return num;
}



猜你喜欢

转载自blog.csdn.net/harvestwu/article/details/78035776