码迷,mamicode.com
首页 > 其他好文 > 详细

表达式树求值

时间:2018-07-21 20:29:45      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:add   stream   ==   children   ber   nullptr   typedef   child   ace   

  code:

#include <iostream>
using namespace std;
typedef enum { NUM, ADD, SUB, MUL, DIV } Type;
#define OPERATOR_CHAR(n) ("+-*/"[n->type - ADD])
typedef struct BN {
    union {
        double number;
        struct BN *children[2];
    } u;
    Type type;
    BN()
    {
        for (int i = 0; i < 2; i++)
            u.children[i] = nullptr;
    }
} Node;
bool isdigit(char s)
{
    if (s >= ‘0‘ && s <= ‘9‘) return true;
    return false;
}
void parse(Node *& n, char *& s)
{
    if (*s == ‘\0‘ || n) return ;
    else
    {
        n = new BN();
        if (isdigit(*s))
        {
            n->type = NUM;
            n->u.number = double(*s - ‘0‘);
            s++;
            return ;
        }
        else
        {
            switch (*s)
            {
                case ‘+‘: n->type = ADD; break;
                case ‘-‘: n->type = SUB; break;
                case ‘*‘: n->type = MUL; break;
                case ‘/‘: n->type = DIV; break;
                default: delete n; s++; return;
            }
            s++;
            parse(n->u.children[0], s);
            parse(n->u.children[1], s);
        }
    }
}
void printInfix(Node* n)
{
    if (n)
    {
        if (n->type == NUM)
            cout << n->u.number;
        else
        {
            cout << ‘(‘;
            printInfix(n->u.children[0]);
                cout << ‘ ‘ << OPERATOR_CHAR(n) << ‘ ‘;
            printInfix(n->u.children[1]);
            cout << ‘)‘;
        }
    }
}
double eval(Node* n)
{
    switch (n->type)
    {
    case ADD: return eval(n->u.children[0]) + eval(n->u.children[1]);
    case SUB: return eval(n->u.children[0]) - eval(n->u.children[1]);
    case MUL: return eval(n->u.children[0]) * eval(n->u.children[1]);
    case DIV: return eval(n->u.children[0]) / eval(n->u.children[1]);
    case NUM: return n->u.number;
    default: return 0.0;
    }
}
void destory(Node *& n)
{
    if (n)
    {
        for (int i = 0; i < 2; i++)
            destory(n->u.children[i]);
        delete n;
    }
}
int main()
{
    char s[] = "*+12-34", *p = s;
    Node* root = nullptr;

    parse(root, p);
    printInfix(root);
    cout << " = " << eval(root) << endl;
    destory(root);
    return 0;
}

  之前看了叶大(milo yip)的文章,发现他的实现中一些地方处理得很好,比如

#define OPERATOR_CHAR(n) ("+-*/"[n->type - ADD])

  以及递归的写法,然后,自己之前没写过如何求表达式树的值,正好今天做了一道表达式求值的题,想起来叶大的文章,于是仿照着写了一个,差不多就是默写了一遍吧~,但更厉害的是叶大将表达式树可视化的算法orz。。。画非满二叉树我曾想了好久也没想出解决办法。

  这个递归的写法还有个好处就是没有使用额外的数据结构,当然,递归本身就会产生递归栈。但与迭代+栈的算法思路相反,这个算法是自上而下建立表达式树。

  

  

表达式树求值

标签:add   stream   ==   children   ber   nullptr   typedef   child   ace   

原文地址:https://www.cnblogs.com/darkchii/p/9342436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!