calculator.h

来自「source code for compute,i am sure it wil」· C头文件 代码 · 共 283 行

H
283
字号
# ifndef CALCULATOR_H
# define CALCILATOR_H
# include <iostream.h>
# include <stdlib.h>
# include "Stack.h"

template <class Type>  //计算器的类模板
class calculator
{
public:
	calculator(); //构造函数
	~calculator(); //析构函数
	void run();                     //计算器操作函数
	void clean();           //将两个栈清空
//	void postfix(); //中缀表达式转换成后缀表达式
private:
	void addoperand(Type);                                   // 将操作数压入栈中
	bool get2operands(Type &,Type &); //通过引用取出两个操作数
	void dooperand(char);                      //对取出的两个操作数进行相应的运算
	Type power(Type,int); //幂运算
	bool isdigit(char);   //判断输入的字符是否为操作数
	int isp(char);                                            //操作符栈内优先数
	int icp(char); //操作符栈外优先数
	stack<Type> s;                     //存放操作数的栈
	stack<char> pun;  //存放操作符的栈
};

template <class Type>
calculator<Type>::calculator(){}

template <class Type>
calculator<Type>::~calculator()
{
	clean();
}

template <class Type>
void calculator<Type>::addoperand(Type value)
{
	s.push(value); //将操作数压入栈中
}

template <class Type>
bool calculator<Type>::get2operands(Type &left,Type &right)
{
	if(s.isempty()) //
	{
		cout<<"缺少操作数!"<<endl;
		return false;
	}
	else
	{
		right=s.pop();           //取出右操作数
		if(s.isempty())
		{
			cout<<"缺少操作数!"<<endl;
			return false;
		}
		else
		{
			left=s.pop();           //取出左操作数
			return true;
		}
	}
	return false;
}

template <class Type>
void calculator<Type>::dooperand(char op)
{
	Type left,right;
	bool result;
	result=get2operands(left,right);
	if(result==true) //能取出两个操作数
		switch(op)
	{
		case '+':   //加法运算
			s.push(left+right);
			break;
		case '%':  //求余运算
			s.push((int)left%(int)right);
			break;
		case '-': //减法运算
			s.push(left-right);
			break;
		case '*':  //乘法运算
			s.push(left*right);
			break;
		case '/':  //除法运算
			if(right==0)                     //右操作数即分母为0
			{
				cout<<"分母为零,不能相除!"<<endl;
				break;
			}
			else
			{
				s.push(left/right);
				break;
			}
		case '^':      //幂运算
			s.push(power(left,int(right)));
			break;
	}
	else
		clean();      //不能取出两个操作数就将栈清空
}

template <class Type>
void calculator<Type>::run()
{
	char ch,y='#';         //将优先数最小的"#"压入符号栈
	Type a;
	int item=0;//item为0表示前一步操作是对操作符操作,为1表示前一步操作是对操作数操作(解决符号问
	          //题,默认为操作符操作,则第一个操作数为负数也能作出正确的判断,例如(-1+3)*4=或-1+2=)
	pun.push('#');            //将优先级最低的标识符'#'压入符号栈
	while(cin>>ch,ch!='=')          //输入一个串,以'='作为结束符
	{

		if(isdigit(ch)||(item==0 && ch=='-'))          //碰到数字或者符号
		{
			cin.putback(ch);
			cin>>a;
			s.push(a);
			item=1;        //操作数操作
			cout<<a;

		}
		else
		{
			cout<<ch;
			if(ch==')')            //碰到右括号,进行括号内的表达式的操作
				for(y=pun.pop();y!='(';y=pun.pop())
					dooperand(y);
			else
			{
				for(y=pun.pop();isp(y)>icp(ch);y=pun.pop())       //根据操作符的优先数进行运算
					dooperand(y);
				pun.push(y);
				pun.push(ch);
				item=0;        //操作符操作
			}
		}
	}
	for(y=pun.pop();y!='#';y=pun.pop())
		dooperand(y);
	cout<<"="<<s.gettop()<<endl;          //输出运算结果
}

template <class Type>
void calculator<Type>::clean()
{
	s.makeempty();
	pun.makeempty();
}

template <class Type>
Type calculator<Type>::power(Type val,int exp)          //幂运算
{
	Type mul=1.0;
	if(exp==0) //系数为0
		return 1;
	else
	{
		if(exp>0) //系数<0
		{
			for(;exp>0;exp--)
			    mul=mul*val;
			return mul;
		}
		else //系数>0
		{
			exp=-exp;
			for(;exp>0;exp--)
				mul=mul*val;
			return 1/mul;
		}
		
	}
}

/*template <class Type>
void calculator<Type>::postfix()//专门用来将中缀表达式转换成后缀表达式
{
	char ch,y;
	Type a;
	pun.makeempty();
	pun.push('#');
	while(cin.get(ch),ch!='=')
	{
		if(isdigit(ch))
		{
			cin.putback(ch);
			cin>>a;
			cout<<a<<' ';
		}
		else
		{
			if(ch==')')
				for(y=pun.pop();y!='(';y=pun.pop())
					cout<<y;
				else
				{
					for(y=pun.pop();isp(y)>icp(ch);y=pun.pop())
						cout<<y;
					pun.push(y);
					pun.push(ch);
				}
		}
	}
	for(y=pun.pop();y!='#';y=pun.pop())
		cout<<y;
}*/

template <class Type>
bool calculator<Type>::isdigit(char ch)
{
	switch(ch)
	{
	case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9'://数字
		return true;
	default:
		return false;
	}
}

template <class Type>
int calculator<Type>::isp(char ch)              //栈内优先数
{
	switch(ch)
	{
	case '#':
		return 0;
		break;
	case '(':
		return 1;
		break;
	case '^':
		return 7;
		break;
	case '*':case'/':case'%':
		return 5;
		break;
	case '+':case'-':
		return 3;
		break;
	case')':
		return 8;
		break;
	default:
		cout<<"有错误操作符!"<<endl;
		exit(0);
	}
}

template <class Type>
int calculator<Type>::icp(char ch) //栈外优先数
{
	switch(ch)
	{
	case '#':
		return 0;
		break;
	case '(':
		return 8;
		break;
	case '^':
		return 6;
		break;
	case '*':case'/':case'%':
		return 4;
		break;
	case '+':case'-':
		return 2;
		break;
	case')':
		return 1;
		break;
	default:
		cout<<"有错误操作符!"<<endl;
		exit(0);
	}
}
# endif

⌨️ 快捷键说明

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