📜  使用 C++ 中的类和实现的表达式树(1)

📅  最后修改于: 2023-12-03 15:36:26.833000             🧑  作者: Mango

使用 C++ 中的类和实现的表达式树

在计算机科学中,表达式树是一种基于树形结构的数据结构,用于表示算术表达式。 在表达式树中,每个数值和运算符都是一个节点,子节点是操作数或运算符。

在本文中,我们将使用 C++ 实现表达式树,并使用类来表示节点。以下是实现表达式树的步骤:

步骤一:定义抽象类

我们首先需要定义一个抽象类 Expression,它将作为所有表达式树节点的抽象基类。下面是 Expression 类的定义和成员函数的说明:

class Expression {
public:
    virtual double evaluate() const = 0;  // 计算表达式树的值
    virtual void print() const = 0;      // 打印表达式树的内容
    virtual ~Expression() {};            // 虚析构函数
};

这个抽象类有两个纯虚函数: evaluate() 和 print()。 evaluate() 函数将计算表达式树的值,而 print() 函数将打印表达式树的内容。该类还有一个虚析构函数,因为我们将在派生类中使用动态内存分配。

步骤二:定义派生类

我们将派生两个类,分别表示操作数和运算符。操作数类将包含一个数字,而运算符类将包含两个子节点和一个操作符。下面是这两个类的定义:

class Operand : public Expression {
public:
    Operand(double value) : value_(value) {}  // 构造函数
    virtual double evaluate() const;          // 重载 evaluate() 函数
    virtual void print() const;              // 重载 print() 函数
private:
    double value_;
};

class Operator : public Expression {
public:
    Operator(char op, Expression* left, Expression* right)
        : op_(op), left_(left), right_(right) {} // 构造函数
    virtual double evaluate() const;             // 重载 evaluate() 函数
    virtual void print() const;                 // 重载 print() 函数
    virtual ~Operator();                        // 虚析构函数
private:
    char op_;
    Expression* left_;
    Expression* right_;
};

操作数类只包含一个数字,并实现了 evaluate() 和 print() 函数:

double Operand::evaluate() const {
    return value_;
}

void Operand::print() const {
    std::cout << value_;
}

而运算符类则包含一个操作符以及左、右子节点,并实现了 evaluate() 和 print() 函数:

double Operator::evaluate() const {
    double left = left_->evaluate();
    double right = right_->evaluate();
    switch (op_) {
    case '+': return left + right;
    case '-': return left - right;
    case '*': return left * right;
    case '/': return left / right;
    default: throw std::invalid_argument("Invalid operator");
    }
}

void Operator::print() const {
    std::cout << "(";
    left_->print();
    std::cout << " " << op_ << " ";
    right_->print();
    std::cout << ")";
}

Operator::~Operator() {
    delete left_;
    delete right_;
}

我们使用左子树表示操作数或子表达式。利用这种结构,我们可以定位表达式树中的任何节点,并访问其操作数或操作符。

步骤三:建立表达式树

最后,我们将使用这些类来构建表达式树。以下是一个例子,它构建和打印表达式树 4*(3+2):

#include <iostream>

int main() {
    Expression* root = new Operator('*', 
                                     new Operand(4), 
                                     new Operator('+', 
                                                  new Operand(3), 
                                                  new Operand(2)));
    root->print();  // 打印表达式树的内容
    std::cout << " = " << root->evaluate();  // 计算表达式树的值
    delete root;   // 释放内存
    return 0;
}

运行这个程序,将输出以下内容:

(4 * (3 + 2)) = 20

这说明我们成功地使用 C++ 中的类和实现来表示和计算表达式树。

结论

本文介绍了如何使用 C++ 类和实现来表示和计算表达式树,包括抽象基类、派生类和动态内存分配。表达式树是计算机科学中非常重要和有用的数据结构之一,可以用于计算各种不同的算术表达式。