对于一个给定的逻辑表达式输出其真值表。具体就是借助二叉树来表示逻辑表达式。
1、程序说明文档
本计算程序用于命题逻辑式的计算。 功能概述:按照一定格式(格式稍后说明)输入命题逻辑式,即可得到真值表。 使用说明: 1、为了方便输入,我们将原本的逻辑运算符号进行了修改。在输入表达式时,请将对应符号转换成我们所要求的符号。下面是对应表列: 逻辑非替代符! 合取替代符号* 析取替代符号/ 蕴含替代符号: 等价替代符号= 输入时只需要对公式的符号直接代换输入即可。 2、运算程序仅支持使用大小写字母表示命题变项,且运算过程对大小写敏感。 3、运算公式中仅允许小括号的出现,并且允许小括号的嵌套使用。 4、如果要结束程序,请使用end命令。命令对大小写不敏感。 5、程序正处于测试阶段,希望使用者能提供漏洞测试数据。 6、表达式输入过程中不允许使用任何的不必要的空格,且每次仅仅允许计算一个表达式 7、尽管程序理论上可以输入2*26个不同的命题变元进行运算,但由于其结果指数增长的特性,请不要随意尝试。否则后果自负。
2、源代码:(这里将基础功能暂时封装成类)
1 #include<cstring> 2 #include<cstdio> 3 #include<cstring> 4 #include<ctype.h> 5 #include<string> 6 #include<algorithm> 7 using namespace std; 8 9 class LogicalExpression 10 { 11 private: 12 int maxn; 13 const char optr[6]="!*/:=";//运算符 14 int *lch=nullptr; 15 int *rch=nullptr; 16 char *op=nullptr; 17 int nc=0;//结点个数 18 int MaxnEstimate(char* AimString); 19 int Build_Tree(char* s,int x,int y); 20 int GetValue(char* p,int* v,int root); 21 public: 22 LogicalExpression(){}; 23 ~LogicalExpression(){}; 24 void SetMaxn(char* AimString); 25 void BuildLogicalExpressionTree(char* EX); 26 void PresentTree(); 27 void ValueChart(); 28 void Clear(); 29 }; 30 31 int LogicalExpression::GetValue(char* p,int* v,int root) 32 { 33 char ch=op[root]; 34 //printf("%c\n",ch); 35 switch(ch) 36 { 37 case '!':return 1-GetValue(p,v,rch[root]); 38 case '*':return (GetValue(p,v,lch[root])&&GetValue(p,v,rch[root]))?1:0; 39 case '/':return (GetValue(p,v,lch[root])||GetValue(p,v,rch[root]))?1:0; 40 case ':':return (GetValue(p,v,lch[root])==1&&GetValue(p,v,rch[root])==0)?0:1; 41 case '=':return (GetValue(p,v,lch[root])==GetValue(p,v,rch[root]))?1:0; 42 } 43 //运行到此处说明是到达叶子 44 //printf("->%d\n",v[strchr(p,ch)-p]); 45 return v[strchr(p,ch)-p]; 46 } 47 48 void LogicalExpression::ValueChart() 49 { 50 //统计命题个数 51 char temp[nc]; 52 memset(temp,0,sizeof(temp)); 53 int u=0; 54 for(int i=1;i<=nc;i++) 55 { 56 char ch=op[i]; 57 if(strchr(temp,ch)==NULL&&strchr(optr,ch)==NULL)temp[u++]=ch; 58 } 59 sort(temp,temp+u); 60 for(int t=0;t<u;t++)printf("%3c",temp[t]); 61 printf(" ANS\n"); 62 //创建真值分配数组 63 int value[u]; 64 memset(value,0,sizeof(value)); 65 //i=[0,(1<<n)-1]循环 66 for(int i=0;i<(1<<u);i++) 67 { 68 int c=i; 69 for(int k=u-1;k>=0;k--) 70 { 71 value[k]=c%2; 72 c/=2; 73 } 74 //分解i为二进制&&分配到各个命题 75 int ans=GetValue(temp,value,1); 76 for(int t=0;t<u;t++)printf("%3d",value[t]); 77 printf("%3d\n",ans); 78 } 79 // 80 return; 81 } 82 83 void LogicalExpression::BuildLogicalExpressionTree(char* EX) 84 { 85 memset(lch,0,sizeof(lch)); 86 memset(rch,0,sizeof(rch)); 87 memset(op,0,sizeof(op)); 88 int lenth=strlen(EX); 89 Build_Tree(EX,0,lenth); 90 return; 91 } 92 93 int LogicalExpression::MaxnEstimate(char* AimString) 94 { 95 int lenth=strlen(AimString); 96 int num=0; 97 for(int i=0;i<lenth;i++) 98 if(AimString[i]=='('||AimString[i]==')')num++; 99 return lenth-num+1; 100 } 101 102 void LogicalExpression::SetMaxn(char* AimString) 103 { 104 maxn=MaxnEstimate(AimString); 105 lch = new int[maxn+1]; 106 rch = new int[maxn+1]; 107 op = new char[maxn+1]; 108 nc=0; 109 return; 110 } 111 112 void LogicalExpression::Clear() 113 { 114 if(lch!=nullptr){delete[] lch;lch=nullptr;} 115 if(rch!=nullptr){delete[] rch;rch=nullptr;} 116 if(op !=nullptr){delete[] op ;op =nullptr;} 117 maxn=nc=0; return; 118 } 119 120 int LogicalExpression::Build_Tree(char* s,int x,int y) 121 { 122 int c[]={-1,-1,-1,-1,-1}; 123 int u; 124 if(y-x==1)//仅一个字符,建立单独结点 125 { 126 u=++nc; 127 lch[u]=rch[u]=0; 128 op[u]=s[x]; 129 return u; 130 } 131 // 132 int p=0; 133 for(int i=x;i<y;i++)//寻找括号外的运算符 134 { 135 if(s[i]=='(')p++; 136 else if(s[i]==')')p--; 137 else if(!p&&strchr(optr,s[i])!=NULL) c[strchr(optr,s[i])-optr]=i; 138 } 139 // 140 int pst=-1; 141 for(int k=4;k>=0;k--) if(c[k]!=-1) {pst=c[k];break;} 142 //寻找在括号外优先级最低的二目运算符 143 if(pst==-1) return Build_Tree(s,x+1,y-1); 144 //整个式子都被包裹在括号里 145 u=++nc; 146 if(s[pst]=='!') lch[u]=-1;//右子树为-1说明是'!'运算 147 else lch[u]=Build_Tree(s,x,pst); 148 rch[u]=Build_Tree(s,pst+1,y); 149 op[u]=s[pst]; 150 return u; 151 } 152 153 void LogicalExpression::PresentTree() 154 { 155 printf("VertexNum==%d\n--------\n",nc); 156 printf("NUM:"); 157 for(int i=1;i<nc+1;i++)printf("%3d",i); 158 printf("\nVER:"); 159 for(int i=1;i<nc+1;i++)printf("%3c",op[i]); 160 printf("\nLCH:"); 161 for(int i=1;i<nc+1;i++)printf("%3d",lch[i]); 162 printf("\nRCH:"); 163 for(int i=1;i<nc+1;i++)printf("%3d",rch[i]); 164 printf("\n"); return; 165 } 166 167 /************************************************************/ 168 169 int main() 170 { 171 //freopen("input.txt","r",stdin); 172 //freopen("ans.txt","w",stdout); 173 LogicalExpression psd; 174 char aim[100]; 175 memset(aim,0,sizeof(aim)); 176 printf(">>"); 177 while(~scanf("%s",aim)) 178 { 179 if(tolower(aim[0])=='e'&&tolower(aim[1])=='n'&&tolower(aim[2])=='d')break; 180 psd.SetMaxn(aim); 181 psd.BuildLogicalExpressionTree(aim); 182 //psd.PresentTree(); 183 psd.ValueChart(); 184 psd.Clear(); 185 memset(aim,0,sizeof(aim)); 186 printf(">>"); 187 } 188 return 0; 189 }