码迷,mamicode.com
首页 > 编程语言 > 详细

STL简单<stl_algorithms.h>算法的实现

时间:2016-06-06 01:20:51      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

    1.简介

STL标准中,没有区分基本算法和复杂算法,然而SGI STL却把常用的算法定义在<stl_algorithms.h>中。本文介绍部分<stl_algorithms.h>算法的实现,给出实现代码和测试代码。

         本文介绍的算法包括:

1.      mismatch:比较两个序列,指出两者之间第一个不匹配的点,返回一对迭代器,分别指向两序列中不匹配的点;

2.      equal:如果两个序列在 [first, last ] 区间内相等,equal() 返回true,忽略第二个序列的元素多出来的部分;

3.      fill:将 [ first,last ) 内的所有元素值改填为 value;

4.      fill_n:将 [ first,last ) 内的前 n 个元素值改填为 value ,返回迭代器,指向被填入的最后一个元素的下一位置;

5.      iter_sawp:将两个迭代器(ForwardIterator)所指的对象对调;

6.      lexicographical_compare:以“字典排列方式”对两个序列 [first1, last1 ) 和 [ first2, last2 )进行比较;

7.      max、min:比较大小;

 

2.设计与实现

我用VS2013写的程序(github),数值算法的实现版本的位于cghSTL/version/cghSTL-0.5.2.rar

本文介绍的算法实现需要以下文件:

1.    cghVector.h,自己实现的vector,位于cghSTL/sequence containers/cghVector/想了解vector实现细节的同学请移步:STL简单vector的实现

2.      cghUtil.h:算法的输出会用到pair结构体,我把pair自己实现了一遍,位于cghSTL/cghUtil/

3.    cghStl_algobase.h,本文的主角:算法的源码,位于cghSTL/algorithms/

4.   test_algorithms_algobase.cpp,测试文件,位于cghSTL/test/

 

为了增强代码的可读性,我用region把各个算法隔开,如下图所示

技术分享

copy算法的实现略微复杂,单独开博客介绍,其余的算法都很简单,直接上代码吧,注释已经说明了一切~

cghStl_algobase.h

/*******************************************************************
*  Copyright(c) 2016 Chen Gonghao
*  All rights reserved.
*
*  chengonghao@yeah.net
*
*  文件内容:equal、fill、fill_n、iter_sawp、max、min、
			 lexicographical_compare、mismatch、copy 算法的实现
******************************************************************/


#ifndef _CGH_STL_ALGOBASE_
#define _CGH_STL_ALGOBASE_

#include "cghUtil.h"
#include "cghSTL_type_traits.h"
#include "cghSTL_iterator.h"

namespace CGH{

	#pragma region equal

	/* 如果两个序列在 [ first, last ] 区间内相等,equal() 返回true,忽略第二个序列的元素多出来的部分 */
	template<class InputIterator1, class InputIterator2>
	inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
	{
		for (; first1 != last1; ++first1, ++first2)
		{
			if (*first1 != *first2)
			{
				return false ; // 如果同一位置上的两个元素值不相等,返回false
			}
		}
		// 当第一个序列走完时(第二个序列一定要比第一个长,且不考虑第二个序列多出来的部分)
		// 两个序列相同位置的元素全部相等,返回true
		return true ;
	}

	/* 
		如果两个序列在 [ first, last ] 区间内相等,equal() 返回true,忽略第二个序列的元素多出来的部分 
		binaryPredicate:用户自定义的比较函数
	*/
	template<class InputIterator1, class InputIterator2, class binaryPredicate>
	inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, binaryPredicate binary_pred)
	{
		for (; first1 != last1; ++first1, ++first2)
		{
			if (!(binaryPredicate(*first1, *first2)))
			{
				return false ; // 如果同一位置上的两个元素值不相等(采用用户自定义的大小比较函数:binaryPredicate),返回false
			}
		}
		// 当第一个序列走完时(第二个序列一定要比第一个长,且不考虑第二个序列多出来的部分)
		// 两个序列相同位置的元素全部相等,返回true
		return true ;
	}

	#pragma endregion

	#pragma region fill

	/* 将 [ first, last ) 内的所有元素值改填为 value */
	template<class ForwardIterator, class T>
	void fill(ForwardIterator first, ForwardIterator last, const T& value)
	{
		for (; first != last; ++first)
		{
			*first = value ;
		}
	}

	#pragma endregion

	#pragma region fill_n

	/* 将 [ first, last ) 内的前 n 个元素值改填为 value ,返回迭代器,指向被填入的最后一个元素的下一位置 */
	template<class OutputIterator, class size, class T>
	OutputIterator fill_n(OutputIterator first, size n, const T& value)
	{
		for (; n > 0; --n, ++first)
		{
			*first = value;
		}
		return first;
	}

	#pragma endregion

	#pragma region iter_sawp

	/* 将两个迭代器(ForwardIterator)所指的对象对调 */
	template<class ForwardIterator1, class ForwardIterator2>
	void iter_swap(ForwardIterator1 first, ForwardIterator2 last)
	{
		// iterator_traits:特性萃取机,获得迭代器指向的值类型
		std::iterator_traits<ForwardIterator1>::value_type tmp = *first;
		*first = *last;
		*last = tmp;
	}

	#pragma endregion

	#pragma region max  min

	/* 比较大小 */
	template<class T>
	inline const T& max(const T& a, const T& b)
	{
		return a > b ? a : b ;
	}

	/* compare:用户自定义的大小比较函数 */
	template<class T, class compare>
	inline const T& max(const T& a, const T& b, compare comp)
	{
		return comp(a, b) ? a : b ;
	}

	/* 比较大小 */
	template<class T>
	inline const T& min(const T& a, const T& b)
	{
		return a < b ? a : b ;
	}

	/* compare:用户自定义的大小比较函数 */
	template<class T, class compare>
	inline const T& min(const T& a, const T& b, compare comp)
	{
		return comp(a, b) ? b : a ;
	}

	#pragma endregion

	#pragma region lexicographical_compare

	/*
		以“字典排列方式”对两个序列 [ first1, last1 ) 和 [ first2, last2 )进行比较,第一个序列以字典排序不小于第二个序列
		比较操作针对两个序列中对应位置上的元素进行,直到一下情况出现:
		1.两序列同一位置上的元素不相等;
		2.同时到达 last1 和 last2(两序列相等);
		3.到达 last1 或者 last2(两序列不相等);
	*/
	/*
		两序列第一次出现同一位置上元素不相等时,lexicographical_compare() 函数的返回值有一下可能:
		1.如果第一个序列的元素比较小,返回 true ,否则返回 false;
		2.如果到达 last1 而尚未到达 last2,返回 true;
		3.如果到达 last2 而尚未到达 last1,返回 false;
		4.如果同时到达 last1 和 last2(注意,序列的区间是前闭后开,同时到达 last 说明所有元素都匹配),返回false;
	*/
	template<class InputIterator1, class InputIterator2>
	bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
	{
		// 以下任何一个序列到达尾端,就结束。,否则两序列一一比对相应元素
		for (; first1 != last1 && first2 != last2; ++first1, ++first2)
		{
			if (*first1 < *first2)
			{
				return true ; // 第一序列值小于第二序列相应值,返回 true
			}
			if (*first2 < *first1)
			{
				return false ; // 第一序列值大于第二序列相应值,返回 false
			}
			// 如果两序列同一位置元素相等,进入迭代器前进,下一轮比较
		}
		// 如果第一个序列到达尾端,但是第二个序列仍有剩余,那么第一个序列小于第二个序列
		return first1 == last1 && first2 != last2 ;
	}

	/* compare:用户指定的大小比较方法 */
	template<class InputIterator1, class InputIterator2, class compare>
	bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, compare comp)
	{
		for (; first1 != last1 && first2 != last2; ++first1, ++first2)
		{
			if ( comp( *first1, *first2 ) )
			{
				return true ;
			}
			if ( comp(*first2, *first1) )
			{
				return false ;
			}
		}
		return first1 == last1 && first2 != last2 ;
	}

	/* 为了增强效率,设计了特化版,使用原生指针 const unsigned char* */
	bool lexicographical_compare(const unsigned char* first1, const unsigned char* last1, const unsigned char* first2, const unsigned char* last2)
	{
		const size_t len1 = last1 - first1 ; // 第一个序列的长度
		const size_t len2 = last2 - first2 ; // 第二个序列的长度
		const int result = memcmp(first1, first2, CGH::min(len1, len2)); // 使用memcmp比较长度相同的部分
		return result != 0 ? result < 0 : len1 < len2 ; // 如果不相上下,则长度较长者视为比较大
	}
	#pragma endregion

	#pragma region mismatch

	/* 
		比较两个序列,指出两者之间第一个不匹配的点,返回一对迭代器,分别指向两序列中不匹配的点
		如果两序列对应元素都匹配,返回的便是两序列各自的 last 迭代器
		如果第二个序列比第一个序列长,忽略多出来的部分
		默认情况下是 equality 操作符比较元素
	*/
	template<class InputIterator1, class InputIterator2>
	cghPair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
	{
		while (first1 != last1 && *first1 == *first2)
		{
			++first1;
			++first2;
		}
		return cghPair<InputIterator1, InputIterator2>(first1, first2) ;
	}

	/* BinaryPredicator:用户自定义比较操作 */
	template<class InputIterator1, class InputIterator2, class BinaryPredicator>
	cghPair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicator binary_pre)
	{
		while (first1 != last1 && binary_pre(*first1, *first2))
		{
			++first1;
			++first2;
		}
		return cghPair<InputIterator1, InputIterator2>(first1, first2) ;
	}

	#pragma endregion

}

#endif


 

3.测试

测试环节的主要内容已在注释中说明

test_algorithms_algobase.cpp

/*******************************************************************
*  Copyright(c) 2016 Chen Gonghao
*  All rights reserved.
*
*  chengonghao@yeah.net
*
*  文件内容:cghStl_algobase.h 中的数值算法的测试
******************************************************************/

#include "stdafx.h"
#include "cghVector.h"
#include "cghStl_algobase.h"
#include <string>
#include <iterator>
#include "cghUtil.h"

int _tmain(int argc, _TCHAR* argv[])
{
	using namespace::CGH;

	std::cout << "创建vector1,依次 puah_back 1、2、3、4、5" << std::endl << std::endl;
	cghVector<int> vector1;
	vector1.push_back(1);
	vector1.push_back(2);
	vector1.push_back(3);
	vector1.push_back(4);
	vector1.push_back(5);
	std::cout << "创建vector2,依次 puah_back 1、2、8、9、0" << std::endl << std::endl;
	cghVector<int> vector2;
	vector2.push_back(1);
	vector2.push_back(2);
	vector2.push_back(8);
	vector2.push_back(9);
	vector2.push_back(0);
	std::ostream_iterator<int> oite(std::cout, " ");


	std::cout << "***********************测试 mismatch 算法**********************" << std::endl << std::endl;
	std::cout << "返回一对迭代器,指出 vector1 和 vector2 的第一个不相等元素:" ;
	std::cout << *(CGH::mismatch(vector1.begin(), vector1.end(), vector2.begin()).first) << ", ";
	std::cout << *(CGH::mismatch(vector1.begin(), vector1.end(), vector2.begin()).second);
	std::cout << std::endl << std::endl << std::endl;

	std::cout << "************************测试 equal 算法************************" << std::endl << std::endl;
	std::cout << "判断 vector1 和 vector2 是否相等:";
	std::string isEqual = equal(vector1.begin(), vector1.end(), vector2.begin(), vector2.end()) == 0 ? "不相等" : "相等" ;
	std::cout << isEqual << std::endl << std::endl;

	std::cout << "用户指定 less<int>() 函数,判断 vector1 和 vector2 的大小:";
	std::string isLess = equal(vector1.begin(), vector1.end(), vector2.begin(), std::less<int>()) == 0 ? "vector1 小于 vector2" : "vector1 大于 vector2" ;
	std::cout << isLess << std::endl << std::endl << std::endl;


	std::cout << "*************************测试 fill 算法************************" << std::endl << std::endl;
	std::cout << "将 vector1 的所有元素改填为 9:" << std::endl << std::endl;
	CGH::fill(vector1.begin(), vector1.end(), 9);
	for (int i = 0; i < vector1.size(); ++i)
	{
		std::cout << "vector1[" << i << "] = " << vector1[i] << std::endl;
	}
	std::cout << std::endl << std::endl;


	std::cout << "************************测试 fill_n 算法***********************" << std::endl << std::endl;
	std::cout << "将 vector1 的前3个元素改填为 0:" << std::endl << std::endl;
	CGH::fill_n(vector1.begin(), 3, 0);
	for (int i = 0; i < vector1.size(); ++i)
	{
		std::cout << "vector1[" << i << "] = " << vector1[i] << std::endl;
	}
	std::cout << std::endl << std::endl;


	std::cout << "***********************测试 iter_sawp 算法**********************" << std::endl << std::endl;
	std::cout << "交换 vector1[0] 和 vector2[0],交换前,vector1[0] = " << vector1[0] << ",vector2[0] = " << vector2[0] << std::endl;
	CGH::iter_swap(vector1.begin(), vector2.begin());
	std::cout << std::endl;
	std::cout << "交换后,vector1[0] = " << vector1[0] << ",vector2[0] = " << vector2[0] << std::endl;
	std::cout << std::endl << std::endl;


	std::cout << "****************测试 lexicographical_compare 算法***************" << std::endl << std::endl;
	std::string str1[] = {"test", "Cgh"};
	std::string str2[] = {"test", "cgh"};
	std::cout << "现有 str1[] = {\"test\", \"Cgh\"}  和  str2[] = {\"test\", \"cgh\"}" << std::endl << std::endl;
	std::cout << "比较 str1[] 和 str2[] 的大小:" ;
	std::string str1Str2 = CGH::lexicographical_compare(str1, str1 + 1, str2, str2 + 1) == true ? "str1[] 大于 str2[]" : "str1[] 小于 str2[]";
	std::cout << str1Str2 << std::endl;
	std::cout << std::endl << std::endl;

	std::cout << std::endl;
	system("pause");
	return 0;
}


 

结果如下图所示:

技术分享

STL简单<stl_algorithms.h>算法的实现

标签:

原文地址:http://blog.csdn.net/chengonghao/article/details/51591142

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!