计算多项式一种方法是转化为逆波兰式后进行计算。
还有就是可以使用表达式树。
具体原理:
因为 + - * / 运算符是双目运算符,可以将一个表达式放到一颗二叉树上,左右分支为操作数,非叶子节点存放操作符,叶子节点存放数字,每棵子树对应表达式的一部分,每棵子树的根存放当前式子中最后运算的运算符。
如何找到最后运算的运算符:
如果整个表达式包含在括号里就去除外层括号
如果最外层没有括号且表达式的一部分包含在括号里,则括号中的运算符一定不是最后运算的
先乘除后加减
自左向右结合,同优先级取最右面的操作符
在找到一段表达式中最后运算的运算符后递归的对这个运算符的左段和右段的表达式按照相同的原理递归的继续展开
代码部分:
下面的代码只能计算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));
- }
- }