#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define N 1005
#define ll long long
char str[N];
char sta[N];
char a[N];
void houzhui()//數組模擬棧求後綴表達式
{
int top = 0;
while (top) top--;
int len=strlen(str);
int k=0;
// printf("len = %d\n", len);
int i;
for(i = 0; i<len; i++)
{
if(str[i]>='a'&&str[i]<='z')
{
a[k++]=str[i];
// printf("%c", a[k-1]);
}
else if(str[i]==')')
{
while (sta[top]!='(')
{
a[k++]=sta[top];
top--;
}
top--;
}
else
{
if (str[i]=='-'&&str[i]!='>')
{
while (top&&sta[top]=='-')
{
a[k++]=sta[top];
top--;;
}
sta[++top] = str[i];
continue;
}
else if (str[i]=='<')
{
while (top&&sta[top]!='(')
{
a[k++]=sta[top];
top--;;
}
sta[++top] = str[i];
i+=2;
}
else if (str[i]=='-'&&str[i+1]=='>')
{
while (top&&sta[top]=='>'||sta[top]=='+'||sta[top]=='*'||sta[top]=='-')
{
a[k++]=sta[top];
top--;;
}
sta[++top] = str[i + 1];
i++;
}
else if (str[i]=='+')
{
while (top&&sta[top]=='+'||sta[top]=='*'||sta[top]=='-')
{
a[k++]=sta[top];
top--;;
}
sta[++top] = str[i];
}
else if (str[i]=='*')
{
while (top&&sta[top]=='*'||sta[top]=='-')
{
a[k++]=sta[top];
top--;;
}
sta[++top] = str[i];
}
else
sta[++top] = str[i];
}
}
while (top)
{
a[k++]=sta[top];
top--;
}
a[k]='\0';
// for(i=0;i<=k;i++)
// {
// printf("%c", a[i]);
// }
// printf("\n");
}
int ans[N];//真值表
char stkk[N];
int f[30];//記錄第幾個是哪一個字母
int h[30];//
int nt[30];//記錄第幾個字母是哪一個
int dfs(int now, int p, int top)//遞歸求各個子式真值
{
if(now == top+1)
{
int num = 0;
while(num) num--;
int len = strlen(a);
int i;
for(i = 0; i<len; i++)
{
if (a[i] <= 'z' && a[i] >= 'a')
{
int x = a[i] - 'a';
if(x + 'a' == 't') x=1;
else if (x+'a'=='f') x=0;
else x = (( p & (1 << (top-f[x]) )) !=0 );
// printf("x = %d\n", (( p & (1 << (top - f[x]) ))!=0));
stkk[++num] = x;
}
else if (a[i]=='-')
{
int x = (stkk[num]==0);
num--;
stkk[++num] = x;
}
else if (a[i]=='*')
{
int x = stkk[num];
num--;
x = (x==1&&stkk[num]==1);
num--;
stkk[++num] = x;
}
else if (a[i]=='+')
{
int x=stkk[num];
num--;
x=(x==1||stkk[num]==1);
num--;
stkk[++num] = x;
}
else if (a[i]=='>')
{
int x=stkk[num];
num--;
x=(!(x==0&&stkk[num]==1));
num--;
stkk[++num] = x;
}
else if (a[i]=='<'){
int x=stkk[num];
num--;
x=(x==stkk[num]);
num--;
stkk[++num] = x;
}
}
ans[p] = stkk[num];
return stkk[num];
}
int a[2], i;
for(i = 0; i<=1; i++)
{
a[i]= dfs(now+1,p*2+i,top);
}
if(a[0]==2 || a[1]==2) return 2;
else if (a[1] != a[2]) return 2;
else return a[1];
}
void work()
{
memset(h, 0, sizeof(h));
int len = strlen(str);
int i;
for(i=0; i<len; i++)
{
if (str[i] <= 'z'&& str[i] >= 'a') h[str[i]-'a'] = 1;
}
int tot = 0;
for(i=0; i<=26; i++)
{
if (h[i] && i+'a' != 'f' && i+'a' != 't')
{
f[i] = ++tot;
nt[tot] = i;
printf(" %c ", i+'a');
}
}
printf(" ANS \n");
int hb = dfs(1,0,tot);
for(i = 0; i<(1 << tot); i++)
{
int j;
for (j=tot-1;j>=0;j--)
{
if (( i & (1<<j)) >0) printf(" 1 ");
else printf(" 0 ");
}
printf(" %d\n",ans[i]);
}//打印真值表
if (hb==0||tot==0) printf("沒有主合取式\n");
else
{
printf("主合取:");
int flag = 0, j;
for(i=0; i<(1 << tot); i++)
{
if(!ans[i]) continue;
if(flag) printf("+");
flag = 1;
printf("(");
for(j = tot-1; j>=0; j--)
{
if(j != tot-1) printf("*");
if((i&(1<<j)) >0 ) printf("%c",nt[tot-j]+'a');
else printf("-%c",nt[tot-j]+'a');
}
printf(")");
}
printf("\n");
}
if (hb==1||tot==0) printf("沒有主析取\n");
else
{
printf("主析取:");
int flag = 0, j;
for(i=0; i<(1 << tot); i++)
{
if(ans[i]) continue;
if(flag) printf("*");
flag = 1;
printf("(");
for(j = tot-1; j>=0; j--)
{
if (j != tot-1) printf("+");
if ((i&(1<<j))==0) printf("%c",nt[tot-j]+'a');
else printf("-%c",nt[tot-j]+'a');
}
printf(")");
}
printf("\n");
}
return ;
}
int main()
{
printf("+:合取\t*:析取\t-:非\n");
printf("請輸入命題公式:");
scanf("%s", str);
houzhui();
work();
return 0;
}
//-((p+q)*p)
//p*q+r
//1.中綴表達式轉換爲後綴表達式便於計算
//2.DFS二進制枚舉每個狀態並用後綴表達式求值,得到真值表
//3.根據真值表打印主析取函數和主合取函數