STL源码分析——常用算法

自己动手实现了一些常用的算法的STL源码,通过以下几个常见算法的源码分析,以后用STL的算法时,即使不知道其内部实现,但也可以理解其调用的原理了。

1.accumulate

//STL的accumulate源码
template<class InputIterator, class T>
T my_accumulate(InputIterator first, InputIterator last, T val)
{

	for (; first != last; ++first)
	{
		val = val + *first;
	}
	return val;
}
template<class InputIterator, class T, class BinaryFunction>
T my_accumulate(InputIterator first, InputIterator last, T val, BinaryFunction binaryOp)
{
	for (; first != last; ++first)
	{
		val = binaryOp(val, *first);
	}
	return val;
}

class MultClass//仿函数functors
{
public:
	int operator()(int x, int y)
	{
		return x*y;
	}
};
int myfunc(int x, int y)
{
	return x*y;
}

int main()
{
	vector<int>nums = { 10,20,30 };
	cout << my_accumulate(nums.begin(), nums.end(), 0) << endl;
	cout << my_accumulate(nums.begin(), nums.end(), 1, myfunc) << endl;
	cout << my_accumulate(nums.begin(), nums.end(), 1, MultClass()) << endl;


	system("pause");
	return 0;
}

2.for_each

//STL的for_each源码
template<class InputIterator, class UnaryFunction>
UnaryFunction my_for_each(InputIterator first, InputIterator last, UnaryFunction f)//返回类型是一元函数对象
{

	for (; first != last; ++first)
	{
		f(*first);
	}
	return f;
}


class MyClass//仿函数functors
{
public:
	void operator()(int x)
	{
		cout << " " << x;
	}
};
void myfunc(int x)
{
	cout << " " << x;
}

int main()
{
	vector<int>nums = { 10,20,30 };
	my_for_each(nums.begin(), nums.end(), myfunc);
	cout << endl;
	my_for_each(nums.begin(), nums.end(), MyClass());
	cout << endl;
	for (auto&elem : nums)
	{
		elem += 5;
	}
	for (auto elem : nums)
	{
		cout << " " << elem;
	}
	system("pause");
	return 0;
}

3.replace

//STL的replace源码
template<class ForwardIterator, class T>
void my_replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value)
{
	//范围内所有等于old_value者都用new_value取代
	for (; first != last; ++first)
	{
		if (*first == old_value)
			*first = new_value;
	}
}


int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	my_replace(nums.begin(), nums.end(), 20, 5);

	cout << endl;
	for (auto elem : nums)
	{
		cout << " " << elem;//10,5,5,5,30
	}
	system("pause");
	return 0;
}

4.replace_if

//STL的replace_if源码
template<class ForwardIterator, class Predicate, class T>
void my_replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value)
{
	//范围内所有满足pred()为true的元素都用new_value替代
	for (; first != last; ++first)
	{
		if (pred(*first, 20))
			*first = new_value;
	}
}
class MyClass//predicate(谓词函数对象)
{
public:
	bool operator()(int x, int y)
	{
		if (x >= y)
			return true;
		return false;
	}
};
bool myfunc(int x, int y)
{
	if (x >= y)
		return true;
	return false;
}

int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	my_replace_if(nums.begin(), nums.end(), MyClass(), 5);//把nums中所有大于等于20的元素用5替代
	my_replace_if(nums.begin(), nums.end(), myfunc, 5);
	for (auto elem : nums)
	{
		cout << " " << elem;//10,5,5,5,5
	}
	system("pause");
	return 0;
}

5.count

template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type //询问萃取机,询问得到的答案作为函数返回类型
count(InputIterator first, 
      InputIterator last, 
      const T& value){
    typename iterator_traits<InputIterator>::difference_type n = 0;
    for(; first != last; ++first)
        if(*first == value)
            ++n;
    return n;
}

6.count_if

//STL的count_if源码
template<class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type//询问萃取机,询问得到的答案作为函数返回类型
my_count_if(InputIterator first, InputIterator last, Predicate pred)
{
	typename iterator_traits<InputIterator>::difference_type n = 0;
	for (; first != last; ++first)
	{
		if (pred(*first))
			++n;
	}
	return n;
}

class MyClass//predicate(谓词函数对象)
{
public:
	bool operator()(int x)
	{
		if (x == 20)
			return true;
		return false;
	}
};
bool myfunc(int x)
{
	if (x == 20)
		return true;
	return false;
}

int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	cout << my_count_if(nums.begin(), nums.end(), MyClass()) << endl;//统计nums中值为20的元素个数
	cout << my_count_if(nums.begin(), nums.end(), myfunc) << endl;

	system("pause");
	return 0;
}

7.find

//STL的find源码
template <class InputIterator, class T>
InputIterator //函数返回值是InputIterator类型
my_find(InputIterator first, InputIterator last, const T& value)
{
	while (first != last && *first != value)
		++first;
	return first;//返回第一个值为value的元素的iterator
}


int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	auto iter = my_find(nums.begin(), nums.end(), 20);//返回第一个值为20的元素的iterator

	for (auto it = iter; it != nums.end(); it++)
	{
		cout << " " << *it;
	}
	system("pause");
	return 0;
}

8.find_if

//STL的find_if源码
template <class InputIterator, class Predicate>
InputIterator //函数返回值是InputIterator类型
my_find_if(InputIterator first, InputIterator last, Predicate pred)
{
	while (first != last && pred(*first))
		++first;
	return first;//返回第一个值为value的元素的iterator
}

class MyClass//predicate(谓词函数对象)
{
public:
	bool operator()(int x)
	{
		if (x == 20)
			return true;
		return false;
	}
};
bool myfunc(int x)
{
	if (x == 20)
		return true;
	return false;
}
int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	auto iter1 = my_find_if(nums.begin(), nums.end(), myfunc);//返回第一个值为20的元素的iterator
	auto iter2 = my_find_if(nums.begin(), nums.end(), MyClass());//返回第一个值为20的元素的iterator

	for (auto it = iter1; it != nums.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl;
	for (auto it = iter2; it != nums.end(); it++)
	{
		cout << " " << *it;
	}
	system("pause");
	return 0;
}

9.binary_search

二分查找,显然,前提是已经是有序序列。

template <class ForwardIterator,class T>
bool my_binary_search(ForwardIterator first,ForwardIterator last,const T& val)
{
	first = lower_bound(first, last, val);
	return (first != last && !(val < *first));
}
int main()
{
	vector<int>nums = { 10,20,20,20,30 };
	bool res1 = my_binary_search(nums.begin(), nums.end(), 10);
	bool res2 = my_binary_search(nums.begin(), nums.end(), 50);

	cout << res1 << endl;
	cout << res2 << endl;
	system("pause");
	return 0;
}

lower_bound: 在不影响原序列的前提下,找到可以插入的第一个位置。例如序列{10, 10, 10, 20, 20, 20, 30, 30, 30},现在需要插入20,则lower_bound返回指向第一个20的位置的iterator。同理,upper_bound返回指向第一个30的位置的iterator。

template <class ForwardIterator,class T>
ForwardIterator 
my_lower_bound(ForwardIterator first,ForwardIterator last,const T& val)
{
	ForwardIterator it;
	iterator_traits<ForwardIterator>::difference_type count, step;
	count = distance(first, last);
	while (count>0)//二分查找
	{
		it = first;
		step = count / 2;
		advance(it, step);//这是一个iterator adapter,用来使迭代器it前进step步
		if (*it < val)//或者可以是 if(comp (*it, val))
		{
			first = ++it;
			count -= step + 1;
		}
		else count = step;
	}
	return first;
}
int main()
{
	vector<int>nums = { 10,10,10,20,20,20,30 };
	auto iter = my_lower_bound(nums.begin(), nums.end(), 20);
	
	for (auto it = iter; it != nums.end(); it++)
	{
		cout << " " << *it;//20,20,20,30
	}
	system("pause");
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值