表达式的计算 中缀转后缀
先把中缀表达式转换成表达式树保存下来,再用后缀表达式计算,过程比较繁琐
所幸最后还是封装成了一个类
写的很挫的
View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
using namespace std;
int flag;
bool pre;
class calc{
enum Type { DATA,ADD,SUB,MULTI,DIV,OPAREN,CPAREN,EOL};
struct node {
Type type;
double data;
node * lchild,*rchild;
node (Type t,double d = 0.0,node *lc = NULL,node *rc = NULL)
{type=t;data=d;lchild=lc;rchild=rc; }
};
node *root;
node *create(char * &s);
Type getToken(char * &s,double &value);
double result(node *t);
public :
calc(char *s){
flag=0;pre=false;
char ss[160];
int i,j;
int len=strlen(s);
for(i=0,j=0;i<len;i++){
if((s[i]=='+' || s[i]=='-') &&( (i-1)>=0 &&s[i-1]== '(' || i == 0))
ss[j++]='0';
ss[j++]=s[i];
}
ss[j]='\0';
strcpy(s,ss);
root = create(s);}
double result(){
if(root==NULL) return 0.0;
return result(root);
}
};
calc::Type calc::getToken(char * &s,double &data){
char type;
while(*s==' ') ++s;
if(*s>='0' && *s <= '9'){
data=0;
while(*s >= '0' && *s <= '9'){data=data*10+*s-'0';++s;}
return DATA;
}
if(*s=='\0') return EOL;
type = *s;++s;
switch(type){
case '+': return ADD;
case '-': return SUB;
case '*': return MULTI;
case '/': return DIV;
case '(': return OPAREN;
case ')': return CPAREN;
default : return EOL;
}
}
double calc::result(node *t){
double num1,num2;
if(t->type == DATA) return t->data;
num1=result(t->lchild);
num2=result(t->rchild);
switch(t->type){
case ADD: t->data=num1+num2;break;
case SUB: t->data=num1-num2;break;
case MULTI:t->data=1.0*num1*num2;break;
case DIV: t->data=1.0*num1/num2;break;
}
return t->data;
}
calc::node *calc::create(char * &s){
node *p,*pp,*new_node,*root=NULL;
Type returnType;
double value;
while(*s){
returnType = getToken(s,value);
switch ( returnType){
case DATA:
case OPAREN:
flag++;
pre=false;
if(returnType == DATA) p = new node(DATA,value);
else {
p=create(s);
pp=p;
}
if(root == NULL) root=p;
else if(root->rchild == NULL) root->rchild=p;
else root->rchild->rchild=p;
break;
case CPAREN:flag--;pre=true;return root;
case EOL:pre=false;return root;
case ADD:
case SUB:;
root=new node (returnType,0,root);
break;
case MULTI:
case DIV:
if(pre) {
if(pp==root) root=new node (returnType,0,root);
else root->rchild=new node(returnType,0,root->rchild);
}
else {
if(root->type==DATA || root->type==MULTI || root->type == DIV)
root=new node (returnType,0,root);
else root->rchild=new node(returnType,0,root->rchild);
}
pre=false;
break;
}
}
return root;
}
int main(){
int i,j;
char str[200];
while(scanf("%s",str)!=EOF){
calc cases(str);
printf("%.4lf\n",cases.result());
}
return 0;
}
/*
(1-(2-3)*2)/(-1)
*/