思路是先把中缀表达式转成后缀表达式,然后建树求解。代码应该是很好理解的,但是想了很久也不明白问题出在哪。
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int n;
char s[N],t[N];
int tot;
char S[N],top;
int S2[N],l[N],r[N],root;
int ans1,ans2;
int dfs(int u)
{
if(t[u] == '0' || t[u] == '1')return t[u]-'0';
int L = dfs(l[u]);
if(L == 0 && t[u] == '&')
{
ans1++;
return 0;
}
if(L == 1 && t[u] == '|')
{
ans2++;
return 1;
}
int R = dfs(r[u]);
return R;
}
int main()
{
scanf("%s",s+1),n = strlen(s+1);
for(int i = 1;i <= n;i++)
{
if(s[i] == '0' || s[i] == '1')t[++tot] = s[i];
else
{
if(s[i] == '&'){while(S[top]=='&'&&top)t[++tot] = S[top--];S[++top]='&';}
if(s[i] == '|'){while(S[top]!='('&&top)t[++tot] = S[top--];S[++top]='|';}
if(s[i] == '(')S[++top] = s[i];
if(s[i] == ')'){while(S[top]!='('&&top)t[++tot] = S[top--];top--;}
}
}
while(top)t[++tot] = S[top--];
//for(int i = 1;i <= tot;i++)printf("%c",t[i]);
//printf("\n");
for(int i = 1;i <= tot;i++)
{
if(t[i] == '0' || t[i] == '1')S2[++top] = i;
else
{
r[i] = S2[top--],l[i] = S2[top--];
S2[++top] = root = i;
}
}
//for(int i = 1;i <= tot;i++)printf("(%d)-%d-%d\n",i,l[i],r[i]);
printf("%d\n",dfs(tot));
printf("%d %d\n",ans1,ans2);
return 0;
}