代码改变世界

MyGrowStack

2012-03-12 22:26  javaspring  阅读(238)  评论(0)    收藏  举报
//MyGrowStack.h

#if !defined (STACK_H)
#define  STACK_H

const int InitStack=1;
const int ShrinkNum=8;
const int Maxbufsize=20;
const int TokError=0;
const int TokNum=1;


class IStack
{
	friend class StackSeq;
public:
	IStack();
	~IStack();
	int Pop();
	void Push(int n);
    int Top() const;
	bool IsEmpty() const;
private:
	void Shrink();
	void Grow();
	int* _arr;
	int _capacity;
	int _top;
};

class StackSeq
{
public:
	StackSeq(IStack const& stack);
	bool AtEnd() const;
	void Advance();
    int GetNum() const;
private:
	int _iCurr;
	IStack const& _stack;
};

class Input
{
public:
	Input();
	int Token() const;
	int Number() const;
private:
	char _buf[Maxbufsize];
	int _token;
};

class Calculator
{
public:
	Calculator(){}
   IStack const& GetStack() const { return _stack;}
   bool Execute(Input const& input);
private:
   int Calculate(int num1,int num2,int token) const;
   IStack  _stack;
};

#endif

//main.cpp

#include <iostream>
#include "MyGrowStack.h"

int main()
{
    Calculator theCalculator;
	bool statue;

	do 
	{
		std::cout<<">";
		Input input;
		statue=theCalculator.Execute(input);
		if (statue)
		{
			for (StackSeq seq(theCalculator.GetStack());!seq.AtEnd();seq.Advance())
			{
				std::cout<<"  "<<seq.GetNum()<<std::endl;
			}
		}
	} while (statue);
	return 0;
}


//MyGrowStack.h

#include <iostream>
#include <cctype>
#include <cstdlib>
#include <cassert>
#include "MyGrowStack.h"

IStack::IStack():_top(0),_capacity(InitStack)
{
   _arr=new int[_capacity];
}
IStack::~IStack()
{
	delete []_arr;
}

void IStack::Shrink()
{
    int * newArr=new int[_top*2];
	for (int i=_top-1;i!=0;i--)
	{
		newArr[i]=_arr[i];
	}
	delete _arr;

	_capacity=_top*2;

	_arr=newArr;

}
void IStack::Push(int n)
{
	assert(_top<=_capacity);
	if (_top==_capacity)
	{
		Grow();
	}
	_arr[_top++]=n;
}

int IStack::Pop() 
{
	assert(0<_top);
	if (_top*3<=_capacity)
	{
		Shrink();
	}
	return _arr[--_top];
}

int IStack::Top() const
{
	assert(_top>0);
	return _arr[_top-1];
}

bool IStack::IsEmpty() const
{
	return _top==0;
}

void IStack::Grow()
{
	std::cout<<"Doubling stack from "<<_capacity<<std::endl;
	int *pTemp=new int[_capacity*2];
	for (int i=0;i!=_capacity;i++)
	{
		pTemp[i]=_arr[i];
	}
	_capacity+=_capacity;
	delete []_arr;
	_arr=pTemp;
}

StackSeq::StackSeq(IStack const& stack):_stack(stack),_iCurr(0)
{

}

bool StackSeq::AtEnd() const
{
	return _iCurr==_stack._top;
}

void StackSeq::Advance()
{
	assert(!AtEnd());
	++_iCurr;
}

int StackSeq::GetNum() const
{
	assert(!AtEnd());
	return _stack._arr[_iCurr];
}

Input::Input()
{
	std::cin>>_buf;
	int c=_buf[0];
	if (std::isdigit(c))
	{
		_token=TokNum;
	}
	else if (c=='+'||c=='*'||c=='/'||c=='|'||c=='&')
	{
		_token=c;
	}
	else if (c=='-')
	{
		if (std::isdigit(_buf[1]))
		{
			_token=TokNum;
		}
		else
			_token=c;
	}
	else
		_token=TokError;
}

int Input::Token() const
{
	return _token;
}

int Input::Number() const
{
	assert(_token==TokNum);
	return std::atoi(_buf);
}

bool Calculator::Execute(Input const& input)
{
	int token=input.Token();
	bool statue=false;

	if (token==TokError)
	{
		std::cout<<"Unkonw token!"<<std::endl;
	}
	else if (token==TokNum)
	{
        _stack.Push(input.Number());
		statue=true;
	}
	else
	{
        if (_stack.IsEmpty())
        {
			std::cout<<"Stack is empty!"<<std::endl;
        }
		else
		{
             int num1=_stack.Pop();
			 int num2;
			 if (_stack.IsEmpty())
			 {
                 num2=num1;
			 }
			 else
				 num2=_stack.Pop();
			 _stack.Push(Calculate(num1,num2,token));
			 statue=true;
		}
	}
	return statue;
}

int Calculator::Calculate(int num1,int num2,int token) const
{
    int result;
	switch(token)
	{
	case '+':
		result=num1+num2;
		break;
	case '-':
		result=num1-num2;
		break;
	case '|':
		result=num1|num2;
		break;
	case '&':
		result=num1&num2;
		break;
	case '*':
		result=num1*num2;
		break;
	case '/':
		result=num1/num2;
		break;
	default:
		break;
	}
	return result;
}