自己动手实现了一些常用的算法的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;
}