기본 STL Conatainer 기능에 추가적인 기능을 넣기 위해 별도로 Template을 이용하여 만듬

공통 추가 기능 : 분산, 표준 편차, 최대 최소값 반환, 평균값, 총합 값

////////// smart stack /////////////
#pragma once

#include <stack>
#include <limits>

using namespace std;

namespace assignment3
{
	template <typename T>
	class SmartStack
	{
	public:
		SmartStack();
		SmartStack(const SmartStack& rhs);
		~SmartStack();
		SmartStack<T>& operator=(const SmartStack& rhs);

		T GetMax() const;
		T GetMin() const;
		double GetAverage() const;
		T GetSum() const;
		double GetVariance() const;
		double GetStandardDeviation() const;

		void Push(const T number);
		T Pop();
		T Peek() const;
		unsigned int GetCount() const;
		bool Empty() const;
	private:
		stack<T>* mMinStack;
		stack<T>* mMaxStack;
		T mTotal;
		double mSqureTotal;

		stack<T>* mStack;

	};

	template <typename T>
	inline SmartStack<T>::SmartStack()
		: mTotal(0)
		, mSqureTotal(0)
	{
		mMinStack = new stack<T>();
		mMaxStack = new stack<T>();

		mStack = new stack<T>();
	}

	template <typename T>
	inline SmartStack<T>::SmartStack(const SmartStack<T>& rhs)
		: mTotal(rhs.mTotal)
		, mSqureTotal(rhs.mSqureTotal)
	{
		mMinStack = new stack<T>(*rhs.mMinStack);
		mMaxStack = new stack<T>(*rhs.mMaxStack);
		mStack = new stack<T>(*rhs.mStack);
	}

	template <typename T>
	inline SmartStack<T>::~SmartStack()
	{
		delete mMinStack;
		delete mMaxStack;
		delete mStack;
	}

	template <typename T>
	inline SmartStack<T>& SmartStack<T>::operator=(const SmartStack<T>& rhs)
	{
		if (this == &rhs)
			return *this;

		delete mMinStack;
		delete mMaxStack;

		mMinStack = new stack<T>(*rhs.mMinStack);
		mMaxStack = new stack<T>(*rhs.mMaxStack);
		mTotal = rhs.mTotal;
		mSqureTotal = rhs.mSqureTotal;

		delete mStack;
		mStack = new stack<T>(*rhs.mStack);

		return *this;
	}

	template <typename T>
	inline void SmartStack<T>::Push(T number)
	{
		mStack->push(number);

		if (mMinStack->empty() == true || mMinStack->top() >= number)
		{
			mMinStack->push(number);
		}

		if (mMaxStack->empty() == true || mMaxStack->top() <= number)
		{
			mMaxStack->push(number);
		}

		mTotal += number;
		mSqureTotal += pow(number, 2);
	}

	template <typename T>
	inline T SmartStack<T>::Pop()
	{
		T number = mStack->top();
		
		if (mMinStack->empty() == false && mMinStack->top() == number)
		{
			mMinStack->pop();
		}

		if (mMaxStack->empty() == false && mMaxStack->top() == number)
		{
			mMaxStack->pop();
		}

		mTotal -= number;
		mSqureTotal -= pow(number, 2);

		mStack->pop();
		return number;
	}

	template <typename T>
	inline T SmartStack<T>::Peek() const
	{
		return mStack->top();
	}

	template <typename T>
	inline unsigned int SmartStack<T>::GetCount() const
	{
		return mStack->size();
	}

	template <typename T>
	inline bool SmartStack<T>::Empty() const
	{
		return mStack->empty();
	}

	template <typename T>
	inline T SmartStack<T>::GetMax() const
	{
		if (Empty() == true)
		{
			return numeric_limits<T>().lowest();
		}

		return mMaxStack->top();
	}

	template <typename T>
	inline T SmartStack<T>::GetMin() const
	{
		if (Empty() == true)
		{
			return numeric_limits<T>().max();
		}

		return mMinStack->top();
	}

	template <typename T>
	inline double SmartStack<T>::GetAverage() const
	{
		T sum = GetSum();
		unsigned int count = GetCount();
		double d = static_cast<double>(sum) / count;
		d = round(d * 1000) / 1000;
		return d;
	}

	template <typename T>
	inline T SmartStack<T>::GetSum() const
	{
		return mTotal;
	}

	template <typename T>
	inline double SmartStack<T>::GetVariance() const
	{
		double count = static_cast<double>(GetCount());
		double dSqureTotalAverage = mSqureTotal / count;
		double dAverage = mTotal / count;
		double dResult = dSqureTotalAverage - pow(dAverage, 2);
		return round(dResult * 1000) / 1000;
	}

	template <typename T>
	inline double SmartStack<T>::GetStandardDeviation() const
	{
		double count = static_cast<double>(GetCount());
		double dSqureTotalAverage = mSqureTotal / count;
		double dAverage = mTotal / count;
		double dResult = dSqureTotalAverage - pow(dAverage, 2);
		return round(sqrt(dResult) * 1000) / 1000;
	}
}
// smart Queue ///////////////////////////////
#pragma once

#include <queue>
#include <limits>

using namespace std;

namespace assignment3
{

	template <typename T>
	class SmartQueue
	{
	public:
		SmartQueue();
		~SmartQueue();

		void Enqueue(const T number);
		T Peek() const;
		T Dequeue();
		T GetMax();
		T GetMin();
		double GetAverage() const;
		T GetSum() const;
		double GetVariance() const;
		double GetStandardDeviation() const;
		unsigned int GetCount() const;
	private:
		T mTotal;
		double mSqureTotal;
		queue<T> mQueue;
	};

	template <typename T>
	inline SmartQueue<T>::SmartQueue()
		: mTotal(0)
		, mSqureTotal(0)
	{
	}

	template <typename T>
	inline SmartQueue<T>::~SmartQueue()
	{
	}

	template <typename T>
	inline void SmartQueue<T>::Enqueue(T number)
	{
		mQueue.push(number);
		mTotal += number;
		mSqureTotal += pow(number, 2);
	}

	template <typename T>
	inline T SmartQueue<T>::Dequeue()
	{
		T number = mQueue.front();

		mTotal -= number;
		mSqureTotal -= pow(number, 2);

		mQueue.pop();
		return number;
	}

	template <typename T>
	inline T SmartQueue<T>::Peek() const
	{
		return mQueue.front();
	}

	template <typename T>
	inline unsigned int SmartQueue<T>::GetCount() const
	{
		return mQueue.size();
	}

	template <typename T>
	inline T SmartQueue<T>::GetMax()
	{
		if (mQueue.empty() == true)
		{
			return numeric_limits<T>().lowest();
		}

		T tMax = mQueue.front();
		unsigned int size = mQueue.size();
		while (size > 0)
		{
			T t = mQueue.front();
			mQueue.pop();
			mQueue.push(t);
			if (t > tMax)
				tMax = t;

			size--;
		}

		return tMax;
	}

	template <typename T>
	inline T SmartQueue<T>::GetMin()
	{
		if (mQueue.empty() == true)
		{
			return numeric_limits<T>().max();
		}

		T tMin = mQueue.front();
		unsigned int size = mQueue.size();
		while (size > 0)
		{
			T t = mQueue.front();
			mQueue.pop();
			mQueue.push(t);
			if (t < tMin)
				tMin = t;

			size--;
		}

		return tMin;
	}

	template <typename T>
	inline double SmartQueue<T>::GetAverage() const
	{
		T sum = GetSum();
		unsigned int count = GetCount();
		double d = static_cast<double>(sum) / count;
		d = round(d * 1000) / 1000;
		return d;
	}

	template <typename T>
	inline T SmartQueue<T>::GetSum() const
	{
		return mTotal;
	}

	template <typename T>
	inline double SmartQueue<T>::GetVariance() const
	{
		double count = GetCount();
		double dSqureTotalAverage = mSqureTotal / count;
		double dAverage = mTotal / count;
		double dResult = dSqureTotalAverage - pow(dAverage, 2);
		return round(dResult * 1000) / 1000;
	}

	template <typename T>
	inline double SmartQueue<T>::GetStandardDeviation() const
	{
		double count = GetCount();
		double dSqureTotalAverage = mSqureTotal / count;
		double dAverage = mTotal / count;
		double dResult = dSqureTotalAverage - pow(dAverage, 2);
		return round(sqrt(dResult) * 1000) / 1000;
	}
}
// QueueStack ///////////////////////////////
// 여러개의 stack을 Queue로 관리하는 container
// stack의 maxsize를 정할 수 있다.
// stack의 maxsize를 초과하면 새로운 stack이 생성되어 Queue에 들어간다.
#pragma once

#include <queue>
#include <stack>
#include <limits>
#include <cmath>
#include "SmartStack.h"

using namespace std;

namespace assignment3
{
	template <typename T>
	class QueueStack
	{
	public:
		QueueStack() = delete;
		QueueStack(const unsigned int maxStackSize);
		QueueStack(const QueueStack<T>& rhs);
		~QueueStack();
		QueueStack<T>& operator=(const QueueStack<T>& rhs);

		void Enqueue(const T number);
		T Peek() const;
		T Dequeue();
		T GetMax() const;
		T GetMin() const;
		double GetAverage() const;
		T GetSum() const;
		unsigned int GetCount() const;
		unsigned int GetStackCount() const;
	private:
		T mTotal;

		queue<SmartStack<T>* >* mQueue;
		const unsigned int mMaxStackSize;
	};

	template <typename T>
	inline QueueStack<T>::QueueStack(const unsigned int maxStackSize)
		: mTotal(0)
		, mMaxStackSize(maxStackSize)
	{
		mQueue = new queue<SmartStack<T>*>();
	}

	template <typename T>
	inline QueueStack<T>::QueueStack(const QueueStack<T>& rhs)
		: mTotal(rhs.mTotal)
		, mMaxStackSize(rhs.maxStackSize)
	{
		mQueue = new queue<SmartStack<T>*>();
	}

	template <typename T>
	inline QueueStack<T>::~QueueStack()
	{
		while (mQueue->empty() == false)
		{
			SmartStack<T>* s = mQueue->front();
			mQueue->pop();
			delete s;
		}
		delete mQueue;
	}

	template <typename T>
	inline QueueStack<T>& QueueStack<T>::operator=(const QueueStack& rhs)
	{
		if (this == &rhs)
			return *this;

		mTotal = rhs.mTotal;

		while (mQueue->empty() == false)
		{
			SmartStack<T>* s = mQueue->front();
			mQueue->pop();
			delete s;
		}
		delete mQueue;

		mQueue = new queue<SmartStack<T>*>();
		
		unsigned int size = rhs.GetStackCount();
		while (size > 0)
		{
			SmartStack<T>* s = rhs.mQueue->front();
			rhs.mQueue->pop();
			rhs.mQueue->push(s);
			mQueue->push(new SmartStack<T>(*s));

			size--;
		}

		return *this;
	}

	template <typename T>
	inline void QueueStack<T>::Enqueue(const T number)
	{
		if (mQueue->empty() == true)
		{
			SmartStack<T>* s = new SmartStack<T>();
			mQueue->push(s);
		}

		SmartStack<T>* s = mQueue->back();
		
		if (s->GetCount() >= mMaxStackSize)
		{
			SmartStack<T>* s = new SmartStack<T>();
			s->Push(number);
			mQueue->push(s);
		}
		else
		{
			s->Push(number);
		}

		mTotal += number;
	}

	template <typename T>
	inline T QueueStack<T>::Peek() const
	{
		SmartStack<T>* s =  mQueue->front();
		return s->Peek();
	}

	template <typename T>
	inline T QueueStack<T>::Dequeue()
	{
		SmartStack<T>* s = mQueue->front();
		T number = s->Peek();
		s->Pop();

		if (s->GetCount() == 0)
		{
			mQueue->pop();
			delete s;
		}

		mTotal -= number;

		return number;
	}

	template <typename T>
	inline unsigned int QueueStack<T>::GetCount() const
	{
		unsigned int size = mQueue->size();

		unsigned int totalSize = 0;
		while (size > 0)
		{
			SmartStack<T>* s = mQueue->front();
			mQueue->pop();
			mQueue->push(s);

			totalSize += s->GetCount();

			size--;
		}

		return totalSize;
	}

	template <typename T>
	inline unsigned int QueueStack<T>::GetStackCount() const
	{
		return mQueue->size();
	}

	template <typename T>
	inline T QueueStack<T>::GetMax() const
	{
		if (mQueue->empty() == true)
		{
			return numeric_limits<T>().lowest();
		}

		SmartStack<T>* s = mQueue->front();
		T tMax = s->GetMax();

		unsigned int size = mQueue->size();
		while (size > 0)
		{
			s = mQueue->front();
			T t = s->GetMax();
			mQueue->pop();
			mQueue->push(s);

			if (t > tMax)
				tMax = t;

			size--;
		}

		return tMax;
	}

	template <typename T>
	inline T QueueStack<T>::GetMin() const
	{
		if (mQueue->empty() == true)
		{
			return numeric_limits<T>().max();
		}

		SmartStack<T>* s = mQueue->front();
		T tMin = s->GetMin();

		unsigned int size = mQueue->size();
		while (size > 0)
		{
			s = mQueue->front();
			T t = s->GetMin();
			mQueue->pop();
			mQueue->push(s);

			if (t < tMin)
				tMin = t;

			size--;
		}

		return tMin;
	}

	template <typename T>
	inline double QueueStack<T>::GetAverage() const
	{
		T sum = GetSum();
		unsigned int count = GetCount();
		double d = sum / static_cast<double>(count);
		d = round(d * 1000) / 1000;
		return d;
	}

	template <typename T>
	inline T QueueStack<T>::GetSum() const
	{
		return mTotal;
	}
}

'포트폴리오' 카테고리의 다른 글

c++ Doubly Linked List  (0) 2019.10.28
c++ binary Search Tree  (0) 2019.10.28
c++ String Class 만들기  (0) 2019.10.28
게이트식스 리뷰영상  (0) 2019.10.07
Projectile 기능  (0) 2019.10.07

+ Recent posts