泛型編程--c++中使用模板對任何類型的數組排序

通過使用c++中的泛型編程機制模板,實現可以對任意類型的數組裏面的數據進行排序。包括我們自己定義的一個類模板的類型。

首先我們對普通的類型int和float類型的數組進行排序,排序的模板:

template <typename T>
class sort_demo{
public:
	static void sort(T *data, int len, bool (*compare)(T &a, T &b))
	{
		T temp;
		assert(len >= 1);
		cout << "len=" << len << "  :";
		for (int i = 0; i < len; i++)
		{
			for (int j = (i + 1); j < len; j++)
			{
				if (compare(data[i], data[j]))
				{
					temp = data[i];
					data[i] = data[j];
					data[j] = temp;
				}
			}
		}
	}
};

裏面的成員方法sort具體的算法是冒泡排序, 其中參數bool (*compare)(T &a, T &b)也是函數模板的指針,並且這個指針可以指向一個類型爲返回值bool,參數爲T& a,T& b的函數模板。這裏具體的指向是比較兩個參數的大小的模板,具體如下:

template<typename T> bool ascend(T &a, T &b)
{
	return a < b ? true : false;
}

template<typename T> bool descend(T &a, T&b)
{
	return a < b ? false : true;
}

分別是升序排列和和降序排列的時候需要用到的。具體使用方法:

	int int_data[] = {4,2,8,1,7,3,2,9,12,5,6,45,23,34};
	float f_data[] = {2.1,1.1,2.3,5.2, 6.0, 7.1,1.5,3.4, 2.3, 2.6, 1.9};

	sort_demo<int>::sort(int_data, sizeof(int_data)/sizeof(int), ascend<int>);
	print(int_data, sizeof(int_data) / sizeof(int));
	sort_demo<int>::sort(int_data, sizeof(int_data) / sizeof(int), descend<int>);
	print(int_data, sizeof(int_data) / sizeof(int));

	sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), ascend<float>);
	print(f_data, sizeof(f_data)/sizeof(float));
	sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), descend<float>);
	print(f_data, sizeof(f_data)/sizeof(float));

由於上面的類模板中的方法sort是static的所以可以使用sort_demo<類型>::sort訪問。

自定義的類模板的類對象進行排序,這裏以計算矩形面積的類模板。如下:

template<typename T>
class cal_size{
private:
	T width;
	T length;
public:
	cal_size() :width(0), length(0){}
	cal_size(T w, T l) :width(w), length(l){}
	T cal_result(void)
	{
		return width*length;
	}
};

其中的方法cal_result返回的就是矩形面積的大小。

對於這種類模板的使用方法:

cal_size<int> area[] = {cal_size<int>(2,4), cal_size<int>(1,4), cal_size<int>(3,2), cal_size<int>(2,4),cal_size<int>(3,3), cal_size<int>(5,2)};
int len = sizeof(area) / sizeof(cal_size<int>);

這個打印是使用函數模板print的特例化,類型是cal_size<int>:

template<> void print<cal_size<int>>(cal_size<int> data[], int len)
{
	cout << "output data: ";
	for (int i = 0; i < len; i++)
	{
		cout << data[i].cal_result() << " ";
	}
	cout << endl;
}

 還有就是當兩個類模板類型cal_size<int>在比較的時候,需要對‘<’‘>’重載運算符。

template<typename T>
bool operator < (cal_size<T>& area1, cal_size<T>& area2)
{
	return area1.cal_result() > area2.cal_result() ? false : true;
}

template<typename T> bool operator > (cal_size<T>& area1, cal_size<T>& area2)
{
	return area1.cal_result() > area2.cal_result() ? true : false;
}

完整的代碼示例: 

#include "stdafx.h"
#include <iostream>
#include <assert.h>
using namespace std;
template<typename T>
void print(T data[], int len)
{
	cout << "output data: ";
	for (int i = 0; i < len; i++)
	{
		cout << data[i] << " ";
	}
	cout << endl;
}

template<typename T> bool ascend(T &a, T &b)
{
	return a < b ? true : false;
}

template<typename T> bool descend(T &a, T&b)
{
	return a < b ? false : true;
}

template <typename T>
class sort_demo{
public:
	static void sort(T *data, int len, bool (*compare)(T &a, T &b))
	{
		T temp;
		assert(len >= 1);
		cout << "len=" << len << "  :";
		for (int i = 0; i < len; i++)
		{
			for (int j = (i + 1); j < len; j++)
			{
				if (compare(data[i], data[j]))
				{
					temp = data[i];
					data[i] = data[j];
					data[j] = temp;
				}
			}
		}
	}
};

template<typename T>
class cal_size{
private:
	T width;
	T length;
public:
	cal_size() :width(0), length(0){}
	cal_size(T w, T l) :width(w), length(l){}
	T cal_result(void)
	{
		return width*length;
	}
};

template<typename T>
bool operator < (cal_size<T>& area1, cal_size<T>& area2)
{
	return area1.cal_result() > area2.cal_result() ? false : true;
}

template<typename T> bool operator > (cal_size<T>& area1, cal_size<T>& area2)
{
	return area1.cal_result() > area2.cal_result() ? true : false;
}

template<> void print<cal_size<int>>(cal_size<int> data[], int len)
{
	cout << "output data: ";
	for (int i = 0; i < len; i++)
	{
		cout << data[i].cal_result() << " ";
	}
	cout << endl;
}
int main()
{
	int int_data[] = {4,2,8,1,7,3,2,9,12,5,6,45,23,34};
	float f_data[] = {2.1,1.1,2.3,5.2, 6.0, 7.1,1.5,3.4, 2.3, 2.6, 1.9};

	sort_demo<int>::sort(int_data, sizeof(int_data)/sizeof(int), ascend<int>);
	print(int_data, sizeof(int_data) / sizeof(int));
	sort_demo<int>::sort(int_data, sizeof(int_data) / sizeof(int), descend<int>);
	print(int_data, sizeof(int_data) / sizeof(int));

	sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), ascend<float>);
	print(f_data, sizeof(f_data)/sizeof(float));
	sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), descend<float>);
	print(f_data, sizeof(f_data)/sizeof(float));

	cout << endl;
	cout << "calculate rect area:";
	cal_size<int> area[] = {cal_size<int>(2,4), cal_size<int>(1,4), cal_size<int>(3,2), cal_size<int>(2,4),cal_size<int>(3,3), cal_size<int>(5,2)};
	int len = sizeof(area) / sizeof(cal_size<int>);
	cout << "len=" << len << endl;
#if 1
	sort_demo<cal_size<int>>::sort(area, sizeof(area)/sizeof(cal_size<int>), ascend<cal_size<int>>);
	print(area, sizeof(area) / sizeof(cal_size<int>));
	sort_demo<cal_size<int>>::sort(area, sizeof(area)/sizeof(cal_size<int>), descend<cal_size<int>>);
	print(area, sizeof(area) / sizeof(cal_size<int>));
#endif
	return 0;
}

代碼運行的結果:

len=14  :output data: 45 34 23 12 9 8 7 6 5 4 3 2 2 1
len=14  :output data: 1 2 2 3 4 5 6 7 8 9 12 23 34 45
len=11  :output data: 7.1 6 5.2 3.4 2.6 2.3 2.3 2.1 1.9 1.5 1.1
len=11  :output data: 1.1 1.5 1.9 2.1 2.3 2.3 2.6 3.4 5.2 6 7.1

calculate rect area:len=6
len=6  :output data: 10 9 8 8 6 4
len=6  :output data: 4 6 8 8 9 10
請按任意鍵繼續. . .

發佈了236 篇原創文章 · 獲贊 39 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章