一.问题描述
给定一个四则运算表达式,将其用树的形式储存起来,如
a+b*(c-d)-e/f;
二.思考
经过对样例的模拟和归纳,大概可以推出来一些规则:1.对于任意的一步计算操作其实都是在两个计算元素之间进行的,并且两元素用运算符号链接
有了这样的一条规律我们很容易就找到了解法,我们只要每次找到一个算式中的那个计算符号就可以确定两个计算元素,然后解析表达式了,很容易知道我们每次要找的其实是优先等级最低的那个运算符号。这里还要注意一个问题就是括号会升高运算符号的优先级
三.实现
这里我们用数组来保存树,然后用中序遍历输出来检验我们算法的正确性
//
// main.cpp
// 表达式树
//
// Created by 张嘉韬 on 16/8/20.
// Copyright © 2016年 张嘉韬. All rights reserved.
//
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
const int maxn=10000;
const int inf=1<<30;
int tree[maxn];
map<char,int> level;
string str;
void init()
{
memset(tree,0,sizeof(tree));
level['*']=2;
level['/']=2;
level['-']=1;
level['+']=1;
}
void print(int s,int e)
{
cout<<"("<<s<<","<<e<<")";
for(int i=s;i<=e;i++)
{
cout<<str[i];
}
cout<<endl;
}
void build(int s,int e,int index)
{
if(str[s]=='('&&str[e]==')') {s++,e--;}
if(s==e) {tree[index]=str[s]; return;}
int temp=0;
int minl=inf,p=0;
for(int i=s;i<=e;i++)
{
if(str[i]=='(') temp+=50;
else if(str[i]==')') temp-=50;
else if((str[i]=='*'||str[i]=='/'||str[i]=='+'||str[i]=='-')&&(temp+level[str[i]]<=minl))
{
minl=temp+level[str[i]];
p=i;
}
}
tree[index]=str[p];
// cout<<str[p]<<endl;
//print(s,p-1);
//print(p+1,e);
build(s,p-1,2*index);
build(p+1,e,2*index+1);
}
void midorder(int index)
{
if(tree[index]==0) return;
midorder(2*index);
cout<<(char)tree[index]<<" ";
midorder(2*index+1);
}
int main(int argc, const char * argv[]) {
freopen("/Users/zhangjiatao/Documents/暑期训练/input.txt","r",stdin);
init();
cin>>str;
build(0,str.length()-1,1);
midorder(1);
return 0;
}