• 表达式求值(表达式树)


    一个非常基础的问题,建出表达式树后在树上DP即可。预处理时记录每个位置之前每种符号最近的出现位置可以做到线性,这里直接写了$O(n^2)$算法。

    注意减法和除法不满足交换律所以要取最右边的一个作为当前子树的根,而乘方要取最左边的。以及注意区分减号和负号。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 using namespace std;
     7 
     8 const int N=1010;
     9 char s[N],op[N];
    10 double ans,val[N];
    11 int n,rt,top,stk[N],lnk[N],ls[N],rs[N];
    12 
    13 bool isop(char ch){ return ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='^'; }
    14 
    15 int build(int l,int r){
    16     if (lnk[l]==r) return build(l+1,r-1);
    17     int rt=0,rt1=0,rt2=0,x=0;
    18     rep(i,l,r){
    19         if (s[i]=='(') i=lnk[i]+1;
    20         if (i>r) break;
    21         if ((s[i]=='+' || s[i]=='-') && (i!=l && !isop(s[i-1]))) rt=i;
    22         if (s[i]=='*' || s[i]=='/') rt1=i;
    23         if (s[i]=='^' && !rt2) rt2=i;
    24     }
    25     if (rt) x=rt; else if (rt1) x=rt1; else x=rt2;
    26     if (!x){ x=r; op[x]='!'; sscanf(s+l,"%lf",&val[x]); return x; }
    27     op[x]=s[x]; ls[x]=build(l,x-1); rs[x]=build(x+1,r); return x;
    28 }
    29 
    30 double dfs(int x){
    31     if (op[x]=='!') return val[x];
    32     double a=dfs(ls[x]),b=dfs(rs[x]),res=0;
    33     if (op[x]=='+') res=a+b;
    34     if (op[x]=='-') res=a-b;
    35     if (op[x]=='*') res=a*b;
    36     if (op[x]=='/') res=a/b;
    37     if (op[x]=='^') res=pow(a,b);
    38     return res;
    39 }
    40 
    41 int main(){
    42     freopen("cal.in","r",stdin);
    43     freopen("cal.out","w",stdout);
    44     scanf("%s",s+1); n=strlen(s+1);
    45     rep(i,1,n){
    46         if (s[i]=='(') stk[++top]=i;
    47         if (s[i]==')') lnk[stk[top]]=i,lnk[i]=stk[top],top--;
    48     }
    49     rt=build(1,n); printf("%.3lf
    ",dfs(rt));
    50     return 0;
    51 }
  • 相关阅读:
    HTML5侧滑聊天面板
    HTML5世界地图
    BZOJ_1042_[HAOI2008]硬币购物_容斥原理+背包
    BZOJ_1342_[Baltic2007]Sound静音问题_单调队列
    BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP
    BZOJ_2595_[Wc2008]游览计划_斯坦纳树
    BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树
    BZOJ_4006_[JLOI2015]管道连接_斯坦纳树
    51nod_1412_AVL树的种类_动态规划
    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10465990.html
Copyright © 2020-2023  润新知