# 表达式二叉树

1382人阅读 评论(0)

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<vector>
#include<climits>
#include<ctime>
#include<stack>
#include<algorithm>
using namespace std;

#define MAX 1005
#define CLR(arr, what) memset(arr, what, sizeof(arr))

struct Node
{
char ope[10];
Node *lchild, *rchild;
Node()
{
CLR(ope, '\0');
lchild = rchild = NULL;
}
};

class Exp
{
private:
Node *root;
int prelen, postlen; //前缀式长度、后缀式长度
int pos; //前缀式计算指针
char str[MAX], pre[MAX], post[MAX]; //中缀式、前缀式、后缀式
stack<double> num; //后缀式计算->数字栈

public:
Exp(char[]); //构造函数
Node* Build_Exp(int start, int end); //建表达式树

void Pre_Order(Node*); //前缀式遍历
void Post_Order(Node*); //后缀式遍历

void PreOut(){cout<<pre<<"="<<endl;} //输出前缀式
void PostOut(){cout<<post<<"="<<endl;} //输出后缀式

double Pre_Calucate(); //前缀式计算
double Post_Calucate(); //后缀式计算

double result(); //输出结果

void clear(Node*);
~Exp(){	clear(root);}; //销毁二叉树
};

Exp::Exp(char s[])
{
root = new Node;
pos = -1;
prelen = 0, postlen = 0;
CLR(str, '\0'); CLR(pre, '\0'), CLR(post, '\0');
while(!num.empty())
num.pop();
strcpy(str, s);
root = Build_Exp(0, strlen(str) - 2); //中缀式长度可按题目改变～
}

Node* Exp::Build_Exp(int src, int des)
{
if(src > des)
return 0;
if(str[src] >= '0' && str[src] <= '9' || str[src] == '.')
{
double temp;
int length;
sscanf(&str[src], "%lf%n", &temp, &length);
if(src + length -1 == des)
{
Node* cur = new Node;
sprintf(cur->ope, "%lf", temp);
cur->ope[length] = '\0';
cur->lchild = NULL, cur->rchild = NULL;
return cur;
}
}
int optr1 = -1, optr2 = -1, pos = 0; // +- || ×/
for(int i = src; i <= des; ++i) //寻找树根
{
switch(str[i])
{
case '(': pos++; break;
case ')': pos--; break;
case '+':
case '-': if(pos == 0) optr1 = i; break;
case '*':
case '/': if(pos == 0) optr2 = i; break;
}
}
if(optr1 < 0)
optr1 = optr2;
if(optr1 < 0)
return Build_Exp(src + 1, des - 1); //被括号包围
Node* upper = new Node;
upper->ope[0] = str[optr1];
upper->ope[1] = '\0';
upper->lchild = Build_Exp(src, optr1 - 1); //递归建左子树
upper->rchild = Build_Exp(optr1 + 1, des); //递归建右子树
return upper;
}

void Exp::Pre_Order(Node* rot)
{
if(rot != NULL)
{
sprintf(&pre[prelen], "%s", rot->ope);
prelen += strlen(rot->ope);
pre[prelen++] = ' ';
Pre_Order(rot->lchild);
Pre_Order(rot->rchild);
}
}

void Exp::Post_Order(Node* rot)
{
if(rot != NULL)
{
Post_Order(rot->lchild);
Post_Order(rot->rchild);
sprintf(&post[postlen], "%s", rot->ope);
postlen += strlen(rot->ope);
post[postlen++] = ' ';
}
}

double Exp::Pre_Calucate()
{
pos++;
if(pre[pos] == ' ') pos++;
if(pre[pos] >= '0' && pre[pos] <= '9')
{
double temp;
int length;
sscanf(&pre[pos], "%lf%n", &temp, &length);
pos += length - 1;
return temp;
}
if(pre[pos] == '+')
return Pre_Calucate() + Pre_Calucate();
if(pre[pos] == '-')
return Pre_Calucate() - Pre_Calucate();
if(pre[pos] == '*')
return Pre_Calucate() * Pre_Calucate();
if(pre[pos] == '/')
return Pre_Calucate() / Pre_Calucate();
}

double Exp::Post_Calucate()
{
postlen = strlen(post) - 1; //最后一个是空格
for(int i = 0; i < postlen; ++i)
{
if(post[i] >= '0' && post[i] <= '9') //操作数
{
double temp;
int length;
sscanf(&post[i], "%lf%n", &temp, &length);
i += length - 1;
num.push(temp);
}
else if(post[i] == ' ')
continue;
else//操作符
{
double a, b;
b = num.top(); num.pop();
a = num.top(); num.pop();
switch(post[i])
{
case '+': num.push(a + b); break;
case '-': num.push(a - b); break;
case '*': num.push(a * b); break;
case '/': num.push(a / b); break;
}
}
}
return num.top();
}

double Exp::result()
{
Pre_Order(root);
PreOut();
Post_Order(root);
PostOut();
return Pre_Calucate();
//return Post_Calucate();
}

void Exp::clear(Node* rot)
{
if(rot->lchild != NULL)
clear(rot->lchild);
if(rot->rchild != NULL)
clear(rot->rchild);
delete(rot);
}

int main()
{
int ncase;
scanf("%d", &ncase);
while(ncase--)
{
char s[MAX];
cin>>s;
Exp e(s);
printf("%.2lf\n", e.result());
}
return 0;
}

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
座右铭：
时间并不会因为你的迷茫和迟疑而停留，就在你看这篇文章的同时，不知道有多少人在冥思苦想，在为算法废寝忘食，不知道有多少人在狂热地拍着代码，不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
没有谁生来就是神牛，而千里之行，始于足下！
个人资料
• 访问：1804898次
• 积分：18205
• 等级：
• 排名：第545名
• 原创：317篇
• 转载：51篇
• 译文：0篇
• 评论：599条
最新评论