📄 pex5_8.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 + -