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

📄 pex5_8.h

📁 数据结构C++代码,经典代码,受益多多,希望大家多多支持
💻 H
字号:
#include <iostream.h>
#include <math.h>

typedef double DataType;
#include "astack.h"

// codes for the Component type field
const short Number = 1, Var = 2, Add = 3, Sub = 4,
			Mul = 5, Div = 6, Exp = 7;

class Calculator
{
	private:
		Stack S;
		
		// used by methods Variable and Eval
		struct Component
		{
			short type;
			double value;
		};
		
		// expsize number of active elements in expComponent
		int expsize;
		Component expComponent[50];

		// private methods used in postfix computation
		int GetTwoOperands(double& operand1, double& operand2);
		void Enter(double num);
		void Compute(char op);
				
	public:
		// constructor
		Calculator(void);
		
		// run calculator and evaluate constant expression
		void Run(void);
		// clear the calculator
		void Clear(void);
		// read an expression in the variable x
		void Variable(void);
		// evaluate an expression in x
		double Eval(double x);
};

// store data value on the stack
void Calculator::Enter(double num)
{
	S.Push(num);
}

// fetch operands from stack and assign value to parameters.
// print message and return False if two operands not present
int Calculator::GetTwoOperands(double& opnd1, double& opnd2)
{
	if (S.StackEmpty())			// check for presence of operand
	{
		cerr << "Missing operand!" << endl;
		return 0;
	}
	opnd1 = S.Pop();			// fetch right-hand operand
	if (S.StackEmpty())
	{
		cerr << "Missing operand!" << endl;
		return 0;
	}
	opnd2 = S.Pop();			// fetch left-hand operand
	return 1;
}

// evaluate an operation
void Calculator::Compute(char op)
{
	int result;
	double operand1, operand2;

	// fetch two operands and identify success or failure
	result = GetTwoOperands(operand1, operand2);

	// if success, evaluate the operator and push value on stack
	// otherwise, clear calculator stack. check for divide by 0.
	if (result == 1)
		switch(op)
		{
			case '+':	S.Push(operand2+operand1);
						break;
						
			case '-':	S.Push(operand2-operand1);
						break;
						
			case '*':	S.Push(operand2*operand1);
						break;
						
			case '/':	if (operand1 == 0.0)
						{
							cerr << "Divide by 0!" << endl;
							S.ClearStack();
						}
						else
							S.Push(operand2/operand1);
						break;

			case '^':	S.Push(pow(operand2,operand1));
						break;
		}
	else
		S.ClearStack();			// error! clear calculator
}

// constructor. clear expsize
Calculator::Calculator(void): expsize(0)
{}
				
// read chars and evaluate a postfix expression. stop on '='.
void Calculator::Run(void)
{
	char c;
	double newoperand;
			
	while(cin >> c, c != '=')	// read until '=' (Quit)
		switch(c)
		{
			case '+':			// check possible operators
			case '-':
			case '*':
			case '/':
			case '^':
				Compute(c);		// have operator; evaluate it
				break;

			default:			
				// not operator, must be operand; put char back
				cin.putback(c);
				// read the operand and store it on the stack
				cin >> newoperand;
				Enter(newoperand);
				break;
		}
	// answer stored on top of stack. print using Peek
	if (!S.StackEmpty())
		cout << S.Peek() << endl;
}

// clear operand stack
void Calculator::Clear(void)
{
	S.ClearStack();
}

// enter an expression in the variable x, terminated by '='.
void Calculator::Variable(void)
{
	char c;
	Component comp;
	double value;

	cout << "Enter a postfix expression in the variable x."
			" Terminate with '='" << endl;
			
	// reinitialize the expComponent array
	expsize = 0;
	
	// read tokens (number,x,+,-,*,/,^) until find '='
	while (cin >> c, c != '=')
	{
		switch(c)
		{
			// handle the operators. initialize the type
			// field of comp appropriately
			case '+':
				comp.type = Add;
				break;
				
			case '-':
				comp.type = Sub;
				break;
				
			case '*':
				comp.type = Mul;
				break;
				
			case '/':
				comp.type = Div;
				break;
				
			case '^':
				comp.type = Exp;
				break;
				
			// handle a variable x. initialize the type
			// field of comp to Var
 			case 'x':
 				comp.type = Var;
 				break;

			// handle a number. assign Number to the type field
			// of comp and assign the numeric value to the value
			// field
			default:			
				cin.putback(c);
				// read the number
				cin >> value;
				comp.type = Number;
				comp.value = value;
				break;
		}
		// update array expComponent
		expComponent[expsize] = comp;
		expsize++;
	}
}

double Calculator::Eval(double x)
{
	Component comp;
	
	// start with a clear stack
	S.ClearStack();
	
	// if expsize is 0, we have no variable expression
	if (expsize == 0)
	{
		cerr << "Eval: no expression entered." << endl;
		return -1.0e-50;
	}

	// go through the variable expression and evaluate it
	for(int i=0;i < expsize;i++)
	{
		// get the current entry
		comp = expComponent[i];
		
		// act on the type field of current entry
		switch(comp.type)
		{
			// for each operator, call Compute
			case Add:
				Compute('+');
				break;
				
			case Sub:
				Compute('-');
				break;
				
			case Mul:
				Compute('*');
				break;
				
			case Div:
				Compute('/');
				break;
				
			case Exp:
				Compute('^');
				break;
				
			// for a variable, push x on the stack
			case Var:
				Enter(x);
 				break;

			// for a number, push its value on the stack
			case Number:			
				Enter(comp.value);
				break;
		}
	}
	// answer stored on top of stack. return using Peek
	if (!S.StackEmpty())
		return S.Peek();
	else
	{
		cout << "Eval: empty expression." << endl;
		return 1.0e-50;
	}
}

⌨️ 快捷键说明

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