⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 term.h

📁 一个我的数据结构解题集合
💻 H
字号:
#ifndef TERM_H__
#define TERM_H__

#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>

#include "IoUtils.h"

using namespace std;

/* 异常类, 在客户端调用了错误的操作时被抛出
 */
class operation_infeasible : public std::runtime_error {
public:
	/* 构造函数
	 */
	explicit operation_infeasible(const string& what_arg)
		: runtime_error(what_arg) {}

	/* 析构函数
	 */
	virtual ~operation_infeasible()
		{}
}; // operation_infeasible


/* 本文件中定义了表达式的各个项
 * 以及这些项的访问器
 */

class Term;			// 表达式项
class Operator;		// 运算符
class Operand;		// 操作数
class Variable;		// 变量
class Number;		// 数值


class TermVisitor {	// 表达式项的访问器
public:

	/* 访问Operator
	 */
	virtual
	void visitOperator(Operator &) = 0;

	/* 访问Operand
	 */
	virtual
	void visitOperand(Operand &) = 0;

	/* 访问Variable
	 */
	virtual
	void visitVariable(Variable &) = 0;

	/* 访问Number
	 */
	virtual
	void visitNumber(Number &) = 0;

}; // TermVisitor



class Term {	// 表达式项
public:

	/*查询该表达式项的字符串表述
	 */
	virtual
	string toString() const = 0;

	/* 接受访问
	 */
	virtual
	void accept(TermVisitor &) = 0;

}; // Term




class Operand : public Term {	// 操作数
public:

	/* 查询该操作数的值
	 */
	virtual
	double getValue() = 0;

	/* 接受访问
	 */
	virtual
	void accept(TermVisitor &v) {
		v.visitOperand(*this);
	} // accept
};




class Variable : public Operand {	// 变量
private:
	string name_;		// 变量名
	double value_;		// 变量值 (需要时从cin读取)
	bool gotValue_;		// 变量值是否已经读取
public:

	/* 构造函数
	 */
	explicit Variable(string name)
		: name_(name), gotValue_(false) {} // Variable(string)

	/*查询该表达式项的字符串表述
	 */
	virtual
	string toString() const {
		return name_;
	} // toString()

	/* 查询该操作数的值
	 * 若尚未读取, 立刻从cin读入
	 */
	virtual
	double getValue() {
		if (!gotValue_) {
			cout << "输入变量" << name_ << "的值: ";
			value_ = getDouble();
			gotValue_ = true;
		}
		return value_;
	} // getValue()

	/* 接受访问
	 */
	virtual
	void accept(TermVisitor &v) {
		v.visitVariable(*this);
	} // accept

}; // Variable




class Number : public Operand {	// 数值
private:
	double value_;
public:
	
	/* 构造函数
	 */
	explicit Number(double val)
		: value_(val) {} // Number(double)

	/*查询该表达式项的字符串表述
	 */
	virtual
	string toString() const {
		stringstream buf;
		buf << value_;
		return buf.str();
	} // toString()

	/* 接受访问
	 */
	virtual
	void accept(TermVisitor &v) {
		v.visitNumber(*this);
	} // accept

	/* 查询该操作数的值
	 */
	virtual
	double getValue() {
		return value_;
	}

}; // Number

class Operator : public Term {	// 运算符
private:
	char o_;		// 运算符的值
	int prec_;		// 运算符的优先级
public:

	/* 运算符的名称
	 */
	enum Optr {
		Add	= '+',	Sub	= '-',
		Mul = '*',	Div = '/',
		Pow = '^',
		LP	= '(',	RP	= ')',
		End	= ';',
	};

	/* 构造函数
	 * 如果参数不是一个运算符, 抛出std::invalid_argument异常
	 */
	explicit Operator(char o)
		: o_(o) {
		prec_ = precedenceOf(o_);
		if (prec_ == 0) {
			stringstream buf;
			buf << "Operator: Invalid argument\n"
				<< "\tOperation: Operator(char)"
				<< "\tArgument: " << o_
				<< endl;
			throw std::invalid_argument(buf.str());
		}
	} // Operator(char)

	/* 查询Operator的值
	 */
	Optr value() const {
		return Optr(o_);
	} // value()

	/* 求op1和op2作用于该Operator后的结果
	 * 对于不支持本操作的Optr, 抛出operation_infeasible异常
	 * 如果除法分母为0 或者 乘方op1为0, op2<0, 抛出std::overflow_error异常
	 */
	double eval(double op1, double op2) const {
		double result = 0;

		switch ( value() ) {
		case Add:	// 加
			result = op1 + op2;
			break;
		case Sub:	// 减
			result = op1 - op2;
			break;
		case Mul:	// 乘
			result = op1 * op2;
			break;
		case Div:	// 除
			if (op2 == 0) {
				throw std::overflow_error("Operator: Devide by zero!\n"
										  "\tOperation: eval(double, double)\n");
			}
			result = op1 / op2;
			break;
		case Pow:	// 乘
			if (op1 == 0.0 && op2 < 0) {
				throw std::overflow_error("Operator: Pow error!\n"
										  "\tReason: x^y is invalid when x==0.0 and y<0\n"
										  "\tOperation: eval(double, double)\n");
			}
			result = pow(op1, op2);
			break;
		default:	// 不支持本操作
			stringstream buf;
			buf << "Operator: Operation infeasible!\n"
				<< "\tOperation: eval(double, double)\n"
				<< "\tOperator value: " << o_
				<< endl;
			throw operation_infeasible( buf.str() );
			break;
		}
		return result;
	}

	/* 查询Operator的优先级
	 */
	int prec() const {
		return prec_;
	} // prec()

	/*查询该表达式项的字符串表述
	 */
	virtual
	string toString() const {
		stringstream buf;
		buf << o_;
		return buf.str();
	} // toString()

	/* 接受访问
	 */
	virtual
	void accept(TermVisitor &v) {
		v.visitOperator(*this);
	} // accept

	/* 查询运算符c的优先级, 优先级高(数值大)的先运算, 
	 * 如果不是运算符返回0
	 */
	static
	int precedenceOf(char c) {
		int prec;

		switch (Optr(c)) {
		case LP: case RP:	// 左右括号及结束符
		case End:
			prec = 1;		// 对左括号有一定意义, 对右括号和结束符没什么意义
			break;
		case Add: case Sub:	// 加减
			prec = 2;
			break;
		case Mul: case Div: // 乘除
			prec = 3;
			break;
		case Pow:			// 乘方
			prec = 4;
			break;
		default:			// 不是运算符
			prec = 0;
			break;
		}

		return prec;
	} // precedence(char)


	/* 查询c是否为运算符
	 */
	static
	bool isOperator(char c) {
		return precedenceOf(c) != 0;
	} // isOperator(char)

}; // Operator

#endif // TERM_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -