粉书练习之表达式树的实现

一.问题描述

给定一个四则运算表达式,将其用树的形式储存起来,如

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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值