c++スタック実装単純計算機


/*       ,                   ,          '#',       ,
 *          ,               ,                    ,
 *                ,           ,         ,           ,
 */
#include 
#include 
#include 
#include  
using namespace std;
const int MAX = 30;
const int DONE = 1;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

//    
template 
class Stack{
public:
	Stack(int MaxStackSize=10);
	~Stack() { delete [] stack;}
	bool IsEmpty() const {return top==-1;}
	bool IsFull() const {return top==MaxTop;}
	T Top() const;
	Stack& Add(const T& x);
	Stack& Del(T& x);
	void MakeEmpty(){top=-1;} //   
	void print(){
		for(int i; i < top + 1; i ++){
			cout<
Stack::Stack(int MaxStackSize){
	MaxTop=MaxStackSize-1;
	stack=new T[MaxStackSize];
	top=-1;
}
template
Stack& Stack::Add(const T& x){
	if(IsFull())
	{cout<
Stack& Stack::Del(T& x){
	if(IsEmpty())
	{cout<
T Stack::Top() const{
	return stack[top];
}

//           
bool isNum(char c){
	if((c > '0'||c == '0')&&(c < '9'||c == '9'))
		return true;
	else
		return false;
}

//          
void deleteBlank(string &s){
	string::iterator i = s.begin();
	while ((i=find(i, s.end(), ' '))!=s.end())
        s.erase(i);
} 

//   
class Calculator{
public:
	Calculator(string s);
	~Calculator();
	int outPriority(char);      //       
	int inPriority(char);       //        
	bool judgePri(char, char);  //              ,                1,    0 
	int judgePri(char);         //         '#'   -1,  ')'   0,     1 
	void dealNum(); 	    //    	
	int calculate();            //   
	void setString(string const s){
		this->s = '#' + s + '#';
		deleteBlank(this->s);   //          
	}
private:
	Stack *s_sym;         //    
	Stack *s_num;          //    
	string s;
};
Calculator::Calculator(string s){
	this->s = '#' + s + '#';
	deleteBlank(this->s);
	s_sym = new Stack(MAX);
	s_num = new Stack(MAX);
} 
Calculator::~Calculator(){
	delete s_sym;
	delete s_num;
}
int Calculator::outPriority(char symble){
	switch(symble){
		case '#':
			return 0;
		case '(':
			return 8;
		case '+':
			return 2;
		case '-':
			return 2;
		case '*':
			return 4;
		case '/':
			return 4;
		case '%':
			return 4;
		case '^':
			return 6;
		case ')':
			return 1;
		default:
			throw 1;
	}
}
int Calculator::inPriority(char symble){
	switch(symble){
		case '#':
			return 0;
		case '(':
			return 1;
		case '+':
			return 3;
		case '-':
			return 3;
		case '*':
			return 5;
		case '/':
			return 5;
		case '%':
			return 5;
		case '^':
			return 7;
		case ')':
			return 8;
		default:
			throw 1;
	}
}
bool Calculator::judgePri(char out, char in){
	if(outPriority(out) > inPriority(in))
		return true;
	else 
		return false;
} 
int Calculator::judgePri(char symble){
	if(symble == '#')
		return -1;
	else if(symble == ')')
		return 0;
	else
		return 1;
}
void Calculator::dealNum(){
	//               ,       ,          
	char _temp = 0; 
	int dtemp1 = 0;
	int dtemp2 = 0; 
	s_sym->Del(_temp);
	s_num->Del(dtemp1);
	s_num->Del(dtemp2); 
	switch(_temp){
		case '+':
			dtemp2 += dtemp1;
			break;
		case '-':
			dtemp2 = dtemp2 - dtemp1;
			break;
		case '*':
			dtemp2 = dtemp2 * dtemp1;
			break;
		case '/':
			if(dtemp1 == 0)
				throw 0;
			else
				dtemp2 = dtemp2 / dtemp1;
			break;
		case '%':
			dtemp2 = dtemp2 % dtemp1;
			break;
		case '^':
			dtemp2 = pow(dtemp2,dtemp1);
			break;
		default:
			throw 1;
	}
	s_num->Add(dtemp2);
}
int Calculator::calculate(){  
	for(int i = 0; i < s.size(); i ++){   //      
		if(isNum(s[i])){
			int temp = (int)(s[i]) - 48;  //char       int ascii    ,  48          
			int _temp = 0;
			if(i > 0 && isNum(s[i - 1])){
				s_num->Del(_temp);
				temp = _temp * 10 + temp;
			}
			s_num->Add(temp);
		}else{ 
			char temp = s[i];
			if(s_sym->IsEmpty()){
				s_sym->Add(temp);
			}else{
				if(judgePri(temp, s_sym->Top())){
					s_sym->Add(temp);  
				}else   if(judgePri(temp) == 1){          //            ,    '#'   ')' 
					while(!judgePri(temp, s_sym->Top())){ //              ,         
						dealNum();
					}
					s_sym->Add(temp);
				
				}else if (judgePri(temp) == -1){
					while(s_sym->Top() != '#'){
						dealNum();
					}
					int result = s_num->Top();
					s_sym->MakeEmpty();
					s_num->MakeEmpty();
					return result;
				}
				else if(judgePri(temp) == 0){
					while(s_sym->Top() != '('){
						dealNum();
					}
					s_sym->Del(temp);
				}
			}
		}
	}
}

int main(int argc, char** argv) {
	try{
		string s = "";
		Calculator c(s);
		while(DONE){
			s = "";
			cout<