[ create a new paste ] login | about

Link: http://codepad.org/osPatcjY    [ raw code | output | fork ]

C++, pasted on Jun 5:
#ifndef vectorX_h
#define vectorX_h
#include <limits>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

template <typename Type>	//每個template只會包含他下面那個物件或函式,因此多個函式都要用template得每個都寫
class vectorX:public vector<Type>
{
	private:
		//vector<Type> vec;	//因為整個vectorX都是繼承自vector,包括vector的member variable,因此不需要再多設一個vector來存資料
	public:
		/*vectorX<Type>(int num = 0, Type value = 0)	//constructor,插入數字版本
		{
			for(vector<Type>::size_type i = 0; i < num, i++)
			{
				vec.push_back(value);
			}

			vSize = num;
		};*/

		vectorX(int num = 0, Type value = 0):vector<Type>(num, value)	//constructor,插入數字版本。直接繼承std::vector裡寫好的constructor的寫法
		{

		};

		vectorX<Type>(int num, const Type* input):vector<Type>(input, input + num)	//constructor,插入陣列版本。直接繼承std::vector裡寫好的constructor的寫法
		{
			//vec<Type>(input, input + num);

			//vSize = num;
		};

		/*vectorX<Type>(const vectorX& v)	//copy constructor
		{
			vec = v;

			vSize = v.vSize;
		};*/

		vectorX(const vectorX& v):vector<Type>(v)	//copy constructor。直接繼承std::vector裡寫好的constructor的寫法
		{

		};

		/*Type& operator[](int place)
		{
			if(place < 0)
				return vec[0];
			else if(place >= vSize)
				return vec[vSize - 1];
			else 
				return vec[place];
		};*/

		vectorX<Type> sum()
		{
			int tail = size();	//記錄尾巴
			Type reg = 0;	//紀錄加總
			vectorX<Type> v = *this;	//由於直接繼承vector裡的member variable,因此要用該vector時以"*this"的形式來呼叫。多創一個vectorX<Type> v來存是怕動到資料的內容

			if(numeric_limits<Type>::is_signed)	
			//numeric_limits<要判斷的型態>::is_signed會判斷該型態是否為signed,是的話會回傳true
			//這裡要先判斷是否為singed的原因,是因為如果是unsigned數,就一定都是正的,那只要一直加到vector爆炸就好,不需要先sort起來
			{
				sort(v.begin(), v.end());	//sort排序,未定義的話預設為由小排到大。括弧裡前面給要排的vector的頭,然後看要排vector裡幾個元素就加多少。全排就直接end()

				//如果sort過後的vector中第一個數字就比0大,那整條vector都大於0,一直往後加就好
				if(*(v.begin()) >= 0)
				{
					for(int head = 0; head < tail; head++)
					{
						if((numeric_limits<Type>::max() / 2) - (reg / 2) < (v[head] / 2))
						//不能寫"reg + vec[head] > numeric_limits<Type>::max()",因為如果左邊已經爆掉了,那會產生無法預知的結果
							throw OverLargest();
						else
							reg += v[head];
					}

					return reg;	//一直都沒有爆掉的話就回傳
				}

				//如果sort過後的vector中最後一個數字比0還小,那整條vector都小於0,一直往後加就好
				if(v[tail - 1] <= 0)	
				{
					for(int head = 0; head < tail; head++)
					{
						if((-numeric_limits<Type>::max() / 2) - (reg / 2) > (v[head] / 2))
							throw OverLowest();
						else
							reg += v[head];
					}

					return reg;
				}

				/*
				如果vector中有負有正,就把頭尾頭尾加在一起,一直這樣往後加
				因為signed有負有正,可能把一條vector裡的負數或正數都加起來就爆了,但全部加起來卻沒爆
				因此先sort過使vector內元素由小排到大之後,頭尾加起來,比較能夠避免這種情況
				*/

				for(int head = 0; head < tail; head++)
				{
					/*
					可能的情形:
					1.頭尾加起來大於最大限制→代表頭尾之間的元素都已經大於0→爆掉回傳OverLargest
					2.頭尾加起來小於最小限制→代表頭尾之間的元素都已經小於0→爆掉回傳OverLowest
					3.頭尾加起來在範圍內,但加上之前的加總大於最大限制→爆掉回傳OverLargest
					4.頭尾加起來在範圍內,但加上之前的加總小於最小限制→爆掉回傳OverLowest
					5.頭尾加起來在範圍內,加上之前的加總在範圍內→更新加總、頭向後移、尾向前移,再跑一次檢查這五種情形
					6.一直到最後都沒超出範圍→回傳加總
					*/

					if(head < tail - 1)		//判斷是不是指到同一元素
					{
						if((numeric_limits<Type>::max() / 2) - (v[head] / 2) < (v[tail - 1] / 2))	//第1種情形
							//要把每個都除以2的原因,是為了避免head是負數,結果一被最大值減下去就爆掉。然後為了方便,不管哪種都除以2這樣
							throw OverLargest();

						if((-numeric_limits<Type>::max() / 2) - (v[head] / 2) > (v[tail - 1] / 2))	//第2種情形
							throw OverLowest();

						if((numeric_limits<Type>::max() / 2) - (reg / 2) < (v[head] / 2) + (v[tail - 1] / 2))	//第3種情形
							throw OverLargest();

						if((-numeric_limits<Type>::max() / 2) - (reg / 2) > (v[head] / 2) + (v[tail - 1] / 2))	//第4種情形
							throw OverLowest();

						reg = reg + v[head] + v[tail-1];		//第5種情形
					}
					else	//頭尾指到同一元素時,為避免多加一次,必須另外處理。由於該元素範圍一定在該型態的最大最小值之間,因此不需要檢測第1第2種情形
					{
						if((numeric_limits<Type>::max() / 2) - (reg / 2) < (v[head] / 2))	//第3種情形
							throw OverLargest();

						if((-numeric_limits<Type>::max() / 2) - (reg / 2) > (v[head] / 2))	//第4種情形
							throw OverLowest();

						reg = reg + v[head];	//第5種情形
					}

					//第5種情形
					head++;
					tail--;
				}

				//第6種情形
				return reg;
			}
			else	//unsigned數的處理方法,只要一直往後加,判斷有沒有爆炸就好
			{
				for(int head = 0; head < tail; head++)
				{
					if((numeric_limits<Type>::max() / 2) - (reg / 2) < (v[head] / 2))
					/*
					不能寫"reg + vec[head] > numeric_limits<Type>::max()",因為如果左邊已經爆掉了,那會產生無法預知的結果
						
					也不能寫"reg - numeric_limits<Type>::max() + vec[head] > 0",因為reg不是小於就是等於型態最大值,減出來結果不是負數就是0
					但unsigned型態不會有負數,會造成大災難
					*/
						throw OverLargest();
					else
						reg += v[head];
				}

				return reg;	//一直都沒有爆掉的話就回傳
			}
		};
};

template<typename Type>
ostream& operator<<(ostream& ostr, const vectorX<Type>& v)
{
	for(int i = 0; i < v.size(); i++)
		ostr << v[i] << ", ";

	return ostr;
};

// Exception classes
class OverLargest
{
	public:
		string message()
		{
			return string("largest overflow");
		};
};

class OverLowest
{
	public:
		string message()
		{
			return string("lowest overflow");
		};
};

#endif


Output:
1
2
3
t.cpp: In member function 'vectorX<Type> vectorX<Type>::sum()':
Line 62: error: there are no arguments to 'size' that depend on a template parameter, so a declaration of 'size' must be available
compilation terminated due to -Wfatal-errors.


Create a new paste based on this one


Comments: