表达式树(代码)

中缀表达式也可以看成一颗二叉树,这棵二叉树的各个结点要么表示四则运算+、-、*、/,要么表示一个非负整数。给出一个表达式树的结点信息,请输出中缀表达式以及该表达式的计算结果。

输入格式:

只包含一组数据: 

第一行一个正整数N(N<=30),代表二叉树的结点个数(结点编号为1到N)。

第二行按结点编号从小到大的顺序给出N个结点的值(用空格隔开),其要么是四则运算符+、-、*、/的其中一个,要么是一个非负整数。

接下来按结点编号从小到大的顺序给出N行,每行为两个编号,分别代表该结点的左孩子编号和右孩子编号,如果不存在左(右)孩子,那么就用字符'-'代替。数据保证编号在1到N之间,且中缀表达式树一定是合法的。

输出格式:

输出一行,即所求的中缀表达式与对应的计算结果(精度保留两位小数),表达式与计算结果之间用空格隔开。 

注意输出的中缀表达式中不允许有空格。数据保证中缀表达式合法,且计算过程中不会出现除数为0的情况。 

限制:

空间限制:128MByte
时间限制:1秒

样例:

输入:

5
* 31 + 4 6
2 3
- -
4 5
- -
- -
输出:

31*(4+6) 310.00

提示:

注意,输出的中缀表达式中,除了最外层以外,内层的每个“左操作数 操作符 右操作数”形式的两侧都要加上一对小括号。例如2+(3*(4/5))就是一个可能的正确输出。
#include<bits/stdc++.h>
const int N = 1e3;
struct node
{
	bool num;
	int data;
	int left, right, father;
} tree[N];
using namespace std;
double cult(int root)
{
	if(!tree[root].left && !tree[root].right)
	{
		return tree[root].data;
	}
	int l = tree[root].left;
	int r = tree[root].right;
	int c = tree[root].data;
	if(c == '+')
	{
		return cult(l) + cult(r);
	}
	else if(c=='-')
	{
		return cult(l) - cult(r);
	}
	else if(c=='*')
	{
		return cult(l) * cult(r);
	}
	else if(c=='/')
	{
		return cult(l) / cult(r);
	}
}
int root;
void in(int p)
{
	if(tree[p].num)
	{
		cout << tree[p].data ;
		return ;
	}
	if(p != root)
	{
		cout << "(";
	}
	in(tree[p].left);
	cout << (char)tree[p].data;
	in(tree[p].right);
	if(p != root)
	{
		cout << ")";
	}
}

int s_num(string s);
int main()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		string c;
		cin >> c;
		int sum = 0;
		if(c.size() > 1)
		{
			for(int j = 0; j < c.size(); j++)
			{
				sum = sum * 10 + (c[j] - '0');
			}
			tree[i].data = sum;
			tree[i].num = 1;
		}
		else if(c[0] >= '0' && c[0] <= '9')
		{
			tree[i].data = c[0] - '0';
			tree[i].num = 1;
		}
		else
		{
			tree[i].data = c[0];
			tree[i].num = 0;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		string a,b;
		cin >> a >> b;
		tree[i].left = s_num(a);
		tree[i].right = s_num(b);
		if(tree[i].left)
		{
			tree[tree[i].left].father = i;
		}
		if(tree[i].right)
		{
			tree[tree[i].right].father = i;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		if(!tree[i].father)
		{
			root = i;
			break;
		}
	}
	in(root);
	double e = cult(root);
	printf(" %.2lf",e);
	return 0;
}

int s_num(string s)
{
	if(s.size() == 1)
	{
		if(s[0]>='0'&&s[0]<='9')
		{
			return s[0]-'0';
		}
		else
		{
			return 0;
		}
	}
	int sum =0;
	for(int j=0; j<s.size(); j++)
	{
		sum=sum*10+(s[j]-'0');
	}
	return sum;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值