枚举真值表生成主合取范式 主析取范式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举真值表生成主合取范式 主析取范式相关的知识,希望对你有一定的参考价值。
方法:将表达式转化为后缀表达式->枚举真值表->输出其合取析取范式
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 5000 4 char s[maxn]; 5 int tail[maxn]; 6 int lens, lent; 7 int stack[maxn]; 8 int spt; 9 int num = 0; 10 int maps[maxn]; 11 int unmaps[maxn]; 12 void push(int c) { 13 stack[spt++] = c; 14 } 15 int top() { 16 return stack[spt - 1]; 17 } 18 void pop() { 19 if (spt>0) spt--; 20 else spt = 0; 21 } 22 void init() { 23 spt = 0; 24 } 25 void error() { 26 printf("表达式错误\n"); 27 } 28 int l, r; 29 void stack_deal(int pt) { 30 while (spt>0 && top() <= pt) { 31 tail[lent++] = -1 * top(); pop(); 32 } 33 push(pt); 34 } 35 void out(int pt) { 36 if (pt>0) { 37 printf("%c ", unmaps[pt]); 38 return; 39 } 40 pt *= -1; 41 if (pt == 1) printf("!"); 42 if (pt == 2) printf("&"); 43 if (pt == 3) printf("|"); 44 if (pt == 4) printf("->"); 45 if (pt == 5) printf("<->"); 46 printf(" "); 47 } 48 int trans_tail(char s[]) { 49 init(); 50 memset(maps, 0, sizeof(maps)); 51 memset(unmaps, 0, sizeof(unmaps)); 52 lent = 0; 53 l = r = 0; 54 num = 0; 55 for (int i = 0; i<lens; i++) { 56 int pt; if ((s[i] >= ‘a‘&&s[i] <= ‘z‘) || (s[i] >= ‘A‘&&s[i] <= ‘Z‘)) { 57 if (maps[s[i]] == 0) { 58 num++; maps[s[i]] = num; 59 unmaps[num] = s[i]; 60 } 61 tail[lent++] = maps[s[i]]; continue; 62 } 63 else if (s[i] == ‘~‘ || s[i] == ‘!‘) 64 stack_deal(1); 65 else if (s[i] == ‘&‘) 66 stack_deal(2); 67 else if (s[i] == ‘|‘) 68 stack_deal(3); 69 else if (s[i] == ‘-‘) { 70 if (s[i + 1] == ‘>‘) { 71 i++; 72 stack_deal(4); 73 } 74 else { 75 error(); return 0; 76 } 77 } 78 else if (s[i] == ‘<‘) { 79 if (s[i + 1] == ‘-‘&&s[i + 2] == ‘>‘) { 80 i += 2; 81 stack_deal(5); 82 } 83 else { 84 error(); return 0; 85 } 86 } 87 else if (s[i] == ‘(‘) { 88 push(6); l++; 89 } 90 else 91 if (s[i] == ‘)‘) { 92 r++; 93 if (l <= 0) { 94 error(); return 0; 95 } 96 while (spt>0 && top() != 6) { 97 // printf("add:%d %d\n",top(),spt); 98 tail[lent++] = -1 * top(); pop(); 99 }// printf("this:%d\n",top()); 100 pop(); l--; r--; 101 } 102 else { 103 error(); return 0; 104 } 105 } 106 while (spt>0) { 107 tail[lent++] = -1 * top(); pop(); 108 } 109 /* printf("%d\n",lent); 110 for(int i=0;i<lent;i++) 111 out(tail[i]);*/ 112 void out_ans(); 113 out_ans(); 114 } 115 typedef long long ll; 116 int bl[maxn]; 117 ll ans1[100000], ans0[100000]; 118 ll ansnum1 = 0, ansnum0 = 0; 119 void out_ans() { 120 ll upnum = (1LL << (num)); 121 int dy = 0; 122 ansnum1 = ansnum0 = 0; 123 printf("是否打印真值表(1 yes 0 no)?\n"); 124 scanf("%d", &dy); 125 if (dy) { 126 for (int i = 1; i <= num; i++) { 127 printf("%c ", unmaps[i]); 128 } 129 printf("\tans\n"); 130 } 131 for (ll i = 0; i<upnum; i++) { 132 // printf("%lld\n",ll); 133 ll bit = i; 134 for (int j = num; j>0; j--) { 135 bl[j] = bit&(1LL); 136 bit = bit >> 1; 137 } 138 init(); 139 for (int j = 0; j<lent; j++) { 140 if (tail[j]>0) { 141 // printf("*%d %d\n",j,maps[tail[j]]); 142 push(bl[tail[j]]); 143 } 144 else if (tail[j]<0) { 145 int a, b; 146 if (tail[j] == -1) { 147 if (spt>0) { 148 a = top(); pop(); 149 } 150 else { 151 error(); return; 152 } 153 a = !a; 154 push(a); continue; 155 } 156 if (spt>1) { a = top(); pop(); b = top(); pop(); } 157 else { 158 error; return; 159 } 160 int c; 161 if (tail[j] == -2) { 162 c = a&&b; 163 //printf("%d %d %d\n",a,b,c); 164 push(c); 165 } 166 else if (tail[j] == -3) { 167 c = a || b; 168 push(c); 169 } 170 else if (tail[j] == -4) { 171 c = 1; 172 if (!a&&b) c = 0; 173 push(c); 174 } 175 else if (tail[j] == -5) { 176 c = 0; 177 if (a&&b) c = 1; 178 if (!a && !b) c = 1; 179 push(c); 180 } 181 } 182 } 183 if (dy) { 184 for (int j = 1; j <= num; j++) { 185 printf("%d ", bl[j]); 186 } 187 printf("\t%d\n", top()); 188 } 189 if (top() == 1) ans1[ansnum1++] = i; 190 if (top() == 0) ans0[ansnum0++] = i; 191 } 192 dy = 0; 193 printf("是否输出主合取范式?1 yes 0 no\n"); 194 scanf("%d", &dy); 195 if (dy) { 196 for (int i = 0; i<ansnum0; i++) { 197 int np = ans0[i]; 198 printf("("); 199 for (int j = num; j>0; j--) { 200 int ws = np & 1; np = np >> 1; 201 if (ws) { 202 printf("┐"); 203 } 204 printf("%c", unmaps[j]); 205 if (j>1) printf("∨"); 206 } 207 printf(")"); 208 if (i<ansnum0 - 1) printf("∧"); 209 } 210 printf("\n"); 211 } 212 dy = 0; 213 printf("是否输出主析取范式?1 yes 0 no\n"); 214 scanf("%d", &dy); 215 if (dy) { 216 for (int i = 0; i<ansnum1; i++) { 217 int np = ans1[i]; 218 printf("("); 219 for (int j = num; j>0; j--) { 220 int ws = np & 1; np = np >> 1; 221 if (!ws) { 222 printf("┐"); 223 } 224 printf("%c", unmaps[j]); 225 if (j>1) printf("∧"); 226 } 227 printf(")"); 228 if (i<ansnum1 - 1) printf("∨"); 229 } 230 printf("\n"); 231 } 232 } 233 void deal() { 234 printf("\n请输入式子:\n"); 235 scanf("%s", s); 236 lens = strlen(s); 237 trans_tail(s); 238 } 239 int main() { 240 printf("输入时请用\n!代表┐\n&代表∧\n|代表∨\n->代表蕴含(减号和大于号)\n<->代表等值(小于号 减号 大于号)\n命题变元用任意大小写字母表示 "); 241 while (1) deal(); 242 }
以上是关于枚举真值表生成主合取范式 主析取范式的主要内容,如果未能解决你的问题,请参考以下文章
Python(离散数学实验)求不超过4个命题变元任意公式的主合取范式主析取范式真值表和成真赋值
数理逻辑命题逻辑的等值演算与推理演算 ( 命题逻辑 | 等值演算 | 主合取 ( 析取 ) 范式 | 推理演算 ) ★★