表达式树计算多项式

来源:互联网 发布:淘宝 授权怎么弄啊 编辑:程序博客网 时间:2024/05/24 11:13

计算多项式一种方法是转化为逆波兰式后进行计算。

还有就是可以使用表达式树。

具体原理:

因为 + - * / 运算符是双目运算符,可以将一个表达式放到一颗二叉树上,左右分支为操作数,非叶子节点存放操作符,叶子节点存放数字,每棵子树对应表达式的一部分,每棵子树的根存放当前式子中最后运算的运算符。

如何找到最后运算的运算符:

如果整个表达式包含在括号里就去除外层括号

如果最外层没有括号且表达式的一部分包含在括号里,则括号中的运算符一定不是最后运算的

先乘除后加减

自左向右结合,同优先级取最右面的操作符

在找到一段表达式中最后运算的运算符后递归的对这个运算符的左段和右段的表达式按照相同的原理递归的继续展开

代码部分:

下面的代码只能计算0-10内整数的加减乘除

#include<iostream>#include<cstring>using namespace std;struct node{   char op;   node *left,*right,*parent;   node(char x):op(x),left(NULL),right(NULL),parent(NULL){}}*root;node* build(char *E,int left,int right){//E是表达式 left和right分别是需要展开的式子在整个表达式中的左右边界   node*pointer=new node(E[left]);   if(left==right) //式子只有一个数字时就结束递归   return pointer;   int a=-1,b=-1,n=0;   for(int i=left;i<=right;i++){      switch(E[i]){         case '(':n++;break;         case ')':n--;break;         case '+':case '-':if(n==0)a=i;break;         case '*':case '/':if(n==0)b=i;      }   }   if(a<0)a=b;//先乘除后加减   if(a<0)return build(E,left+1,right-1);//外围有大括号包围的情况   else{      pointer->op=E[a];      pointer->left=build(E,left,a-1);      pointer->right=build(E,a+1,right);   }   return pointer;}double calculate(node* root){//根据表达式树求值   if(root->op>='0'&&root->op<='9')return root->op-'0';   else{      double ans;      switch(root->op){         case '+':ans=calculate(root->left)+calculate(root->right);break;         case '-':ans=calculate(root->left)-calculate(root->right);break;         case '*':ans=calculate(root->left)*calculate(root->right);break;         case '/':ans=calculate(root->left)/calculate(root->right);break;      }      return ans;      /*关于动态申请的内存回收的问题      因为程序结束后系统会自动回收全部内存就没写释放语句      也可以边计算边释放计算完一个节点后就释放内存      最妥善的处理方式是建一个内存池      */   }}int main(){   char p[1000];   while(cin>>p){      root=build(p,0,strlen(p)-1);      cout<<calculate(root)<<endl;      memset(p,0,sizeof(p));   }}


原创粉丝点击