【离散数学】编程练习:求命题公式的主范式
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define N 50
char input[N];
bool table[N];
int cvt[N];
int value[N];
int order(char c)
{
switch (c)
{
case '#':
return -1;
case '(':
return 0;
case '+':
return 1;
case '-':
return 2;
case '|':
return 3;
case '&':
return 4;
case '!':
return 5;
default:
return 0;
}
}
void postfix()
{
char post[N] = {'\0'};
int index = -1;
char stack[N] = {'#'};
int sub = 0;
int len = strlen(input);
for (int i = 0; i < len; i++)
{
if (input[i] >= 'a' && input[i] <= 'z')
{
post[++index] = input[i];
continue;
}
if (input[i] == '!' || input[i] == '&' || input[i] == '|' || input[i] == '-' || input[i] == '+')
{
while (order(input[i]) <= order(stack[sub]))
post[++index] = stack[sub--];
stack[++sub] = input[i];
continue;
}
if (input[i] == '(')
{
stack[++sub] = input[i];
continue;
}
if (input[i] == ')')
{
while (stack[sub] != '(')
post[++index] = stack[sub--];
sub--;
continue;
}
}
while (sub)
post[++index] = stack[sub--];
strcpy(input, post);
}
int btoi()
{
int sum = 0, weight = 1;
for (int i = 25; i >= 0; i--)
if (table[i])
{
if (cvt[i]) sum += weight;
weight *= 2;
}
return sum;
}
int calc(int a, int b, char c)
{
switch (c)
{
case '&': return a * b;
case '|': if (a + b) return 1; else return 0;
case '-': if (a == 1 && b == 0) return 0; else return 1;
case '+': return !((a + b) & 1);
}
}
int work()
{
int stack[N], ps = -1;
int len = strlen(input);
for (int i = 0; i < len; i++)
{
if (input[i] >= 'a' && input[i] <= 'z')
{
stack[++ps] = cvt[input[i] - 'a'];
continue;
}
if (input[i] == '!')
{
stack[ps] = (stack[ps] + 1) & 1;
continue;
}
int ans = calc(stack[ps - 1], stack[ps], input[i]);
stack[--ps] = ans;
}
return stack[0];
}
void assign()
{
int x = btoi();
int ans = work();
value[x] = ans;}
void generate(char c)
{
while (c <= 'z' && table[c - 'a'] == false)
c++;
if (c > 'z')
{
assign();
return;
}
cvt[c - 'a'] = 0;
generate(c + 1);
cvt[c - 'a'] = 1;
generate(c + 1);
}
int set_order()
{
int v = 0;
memset(table, 0, sizeof(table));
int len = strlen(input);
for (int i = 0; i < len; i++)
{
if (input[i] >= 'a' && input[i] < 'z')
table[input[i] - 'a'] = true;
}
for (int i = 0; i < 26; i++)
if (table[i])
v++;
v = pow(2, v);
return v;
}
void outDis(int sum)
{
int i = 0;
while (i < sum && !value[i]) i++;
if (i >= sum)
{
printf("0 ; ");
return;
}
printf("m%d", i);
for (i++; i < sum; i++)
if (value[i]) printf(" ∨ m%d", i);
printf(" ; ");
}
void outCon(int sum)
{
int i = 0;
while (i < sum && value[i]) i++;
if (i >= sum)
{
printf("1\n");
return;
}
printf("M%d", i);
for (i++; i < sum; i++)
if (!value[i]) printf(" ∧ M%d", i);
printf("\n");
}
void result(int sum)
{
generate('a');
outDis(sum);
outCon(sum);
}
int main()
{ int sum;
scanf("%s", input);
postfix();
sum = set_order();
result(sum);
return 0;
}