/*1139. 电路稳定性
大意:给出一串电路。求出错概率
思路:把如 (A,B)((C)(D),E)转成 (A+B) * ((C)*(D) + E) 一般表达式
然后转换成后缀表达式
如 (A+B) * ((C)*(D) + E) 转成 pre = AB+CD*E+*
遇到+就计算 1-(1-P(A)) * (1-P(B))
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
string expr;
double prb[30];
double ans;
int pri(char a)
{
if(a == '(') return -1;
return (a == '+') ? 1 : 2;
}
// 转换成后缀表达式
void convert()
{
// 转换成一般表达式
//如 (A,B)((C)(D),E)转成 (A+B) * ((C)*(D) + E)
string pre = "";
for(int i = 0; i < expr.length(); i ++)
{
if(expr[i] == ',') pre += '+';
else if(expr[i]==')' && expr[i+1]=='(') pre += ")*";
else pre += expr[i];
}
expr = pre;
// 转换成后缀表达式
//如 (A+B) * ((C)*(D) + E) 转成 pre = AB+CD*E+*
pre = "";
stack<char> sta;
for(int i = 0; i < expr.length(); i ++)
{
if(sta.empty()) { sta.push(expr[i]); continue; }
if(expr[i]=='(') { sta.push(expr[i]); continue; }
else if(expr[i] == ')')
{
while( sta.top() != '(' )
{
pre += sta.top();
sta.pop();
}
sta.pop();
continue;
}
//如果是字母就直接进入后缀表达式
if(isalpha(expr[i])) pre += expr[i];
//如果是+或*
else
{
//若当前优先级高,则直接进入表达式 *高于+,再次为(
if(pri(expr[i]) > pri(sta.top())) sta.push(expr[i]);
else
{
//如果当前优先级低,则把栈中高优先级的一次进入表达式
while(!sta.empty() && pri(expr[i]) <= pri(sta.top()))
{
pre += sta.top();
sta.pop();
}
//然后把当前低的放进栈
sta.push(expr[i]);
}
}
}
//把栈中剩余的操作符放进表达式
while(!sta.empty()) { pre += sta.top(); sta.pop(); }
expr = pre;
}
// 后缀表达式的计算
void calc()
{
stack<double> sta;
for(int i = 0; i < expr.length(); i ++)
{
//元件次序为A B C D E F G...
if(isalpha(expr[i])) sta.push(prb[expr[i]-'A']);
else
{
double num1 = sta.top();
sta.pop();
double num2 = sta.top();
sta.pop();
if(expr[i] == '+')
sta.push( 1-(1-num1)*(1-num2) );
else
sta.push(num1*num2);
}
}
ans = sta.top();
}
int main()
{
int n;
while(cin >> n)
{
cin >> expr;
for(int i = 0; i < n; i ++) cin >> prb[i];
convert();
calc();
printf("%.4lf\n",ans);
}
}
1139. 电路稳定性(转换成一般表达式,用后缀表达式计算)
最新推荐文章于 2024-08-14 17:29:13 发布