您的位置:首页 > 其它

1139. 电路稳定性(转换成一般表达式,用后缀表达式计算)

2013-01-02 19:53 281 查看
/*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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: