STL算法详细解剖——单纯数据处理函数
- 前言
- 1.replace 替代函数值
- 2.replace_copy 替代函数值
- 3.replace_if 替代函数值
- 4.replace_copy_if 替代函数值
- 5.reverse 颠倒排序
- 6.reverse_copy 颠倒排序
- 7.rotate 将元素按某个中间值进行互换
- 7.1.rotate 将元素按某个中间值进行互换
- 8.roate_copy 将元素按某个中间值进行互换
- 9.search 判断是否包含子串
- 10.search_n 查找n个满足条件的元素所组成的子串
- 11.swap_ranges 等长区间的元素进行互换
- 12.transform 提供的仿函数用于区间每个元素
- 13.adjacent_find 查找相邻的重复元素
- 14.unique 移除相邻的重复元素(并不删除空间)
- 15.count 查找某个元素的个数
- 16.count_if 查找某个元素的个数
- 17.find 查找某个元素返回一个迭代器
- 18.find_if 查找某个元素返回一个迭代器
- 19.find_end 查找完全匹配的子串最后出现的位置
- 20.find_first_of 查找目标区的元素在源区第一次出现的位置
- 21.for_each 遍历数据
- 22. generate 将仿函数运行的结果填入源区间元素中
- 23. generate_n 运算结果填写到从迭代器开始的n个元素身上
- 24. includes (应用有序区间),验证目标集合是否为源集合的子集
- 25. max_element 返回一个指向最大元素的迭代器
- 26. merge(应用有序区间)将两个排序的集合存放在另一个空间中
- 27. min_element 返回一个指向最小值的迭代器
- 28. partition 区间内的集合,判断为true的放前面,判断为false放后面
- 29. remove 删除指定元素(并不删除空间)
- 30. remove_copy 删除指定元素,结果存放在另外一个空间
- 31. remove_if remove_copy_if 删除区间内,被仿函数评估为true的元素
- 总结
前言
阅读STL源码剖析有感,简单模拟处理函数的实现,同时也写了部分函数的测试代码,读者这直接复制粘贴使用(若有问题,请多多指出)。这份总结的目的是了解函数背后的运行,体会模板函数与仿函数结合的奥妙。在日常的开发中,可用相关的函数,来满足日常开发的需求。增加代码的可读性,减小代码的体积。(为了防止函数命名冲突,函数前面追加了自定义 USD_ 来重新命名函数)
1.replace 替代函数值
template<class T_iterator,class T>
void replace(T_iterator first, T_iterator last, const T& old_value, const T& new_value)
{
for (;first != last;++first )
{
if (*first == old_value)
{
*first = new_value;
}
}
}
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
replace(vecTest.begin(), vecTest.end(),3,4);
return 0;
}
通过遍历数据,当查找到对应数据时,修改数据值
2.replace_copy 替代函数值
template<class IntputIterator, class OutputIterator, class T>
OutputIterator replace_copy(IntputIterator first, IntputIterator last, OutputIterator result, const T& old_value, const T& new_value)
{
for (; first != last; ++first,++result)
{
*result = *first == old_value ? new_value : *first;
}
return result;
}
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
std::vector<int> vecReslutTest;
vecReslutTest.resize(7);
replace_copy(vecTest.begin(), vecTest.end(), vecReslutTest.begin(),3,4);
return 0;
}
通过遍历数据,当查找到对应数据时,修改数据值。将修改的数据存储到另外一个空间中
3.replace_if 替代函数值
template<class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value)
{
for (; first != last; ++first)
{
if (pred(*first))
{
*first = new_value;
}
}
}
class Predicate
{
public:
Predicate(int x)
{
m_x = x;
}
bool operator()(int value)
{
if (value == m_x)
{
return true;
}
return false;
}
private:
int m_x;
};
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
std::vector<int> vecReslutTest;
vecReslutTest.resize(7);
replace_copy(vecTest.begin(), vecTest.end(), vecReslutTest.begin(),3,4);
replace_if(vecTest.begin(), vecTest.end(), Predicate(3),4);
return 0;
}
上述操作和之前的逻辑相似,此处的设计逻辑可用于以后对不同数据类型的逻辑处理。不同类型的数据修改成不同的仿函数使用
4.replace_copy_if 替代函数值
class Predicate
{
public:
Predicate(int x)
{
m_x = x;
}
bool operator()(int value)
{
if (value == m_x)
{
return true;
}
return false;
}
private:
int m_x;
};
template<class IntputIterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(IntputIterator first, IntputIterator last, OutputIterator result, Predicate pred, const T& new_value)
{
for (; first != last; ++first, result++)
{
*result = pred(*first) ? new_value : *first;
}
return result;
}
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
std::vector<int> vecReslutTest;
vecReslutTest.resize(7);
replace_copy_if(vecTest.begin(), vecTest.end(), vecReslutTest.begin(), Predicate(3), 4);
return 0;
}
此算法和上述相似,只是将修改后的结果存放到另外一个空间
5.reverse 颠倒排序
template<class ForwardIterator1, class ForwardIterator2>
void _iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
typename std::iterator_traits<ForwardIterator1>::value_type tmp = *a;
*a = *b;
*b = tmp;
}
template<class ForwardIterator1, class ForwardIterator2>
void usd_iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
_iter_swap(a,b);
}
template<class ForwardIterator>
void _reverse(ForwardIterator first, ForwardIterator last)
{
while (true)
{
if (first == last || first == --last)
{
return;
}
else
{
usd_iter_swap(first++, last);
}
}
}
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
std::vector<int> vecReslutTest;
vecReslutTest.resize(7);
_reverse(vecTest.begin(), vecTest.end());
return 0;
}
遍历数据,首尾数据互换。颠倒结束后,返回排序
6.reverse_copy 颠倒排序
template<class IntputIterator, class OutputIterator>
void reverse_copy(IntputIterator first, IntputIterator last, OutputIterator result)
{
while (first != last)
{
--last;
*result = *last;
result++;
}
}
int main()
{
int a[] = {1,2,3,3,3,5,6};
std::vector<int> vecTest(a, a+7);
std::vector<int> vecReslutTest;
//replace(vecTest.begin(), vecTest.end(), 3, 4);
vecReslutTest.resize(7);
//replace_copy(vecTest.begin(), vecTest.end(), vecReslutTest.begin(),3,4);
//replace_if(vecTest.begin(), vecTest.end(), Predicate(3),4);
//replace_copy_if(vecTest.begin(), vecTest.end(), vecReslutTest.begin(), Predicate(3), 4);
//_reverse(vecTest.begin(), vecTest.end());
reverse_copy(vecTest.begin(), vecTest.end(), vecReslutTest.begin());
return 0;
}
逆序遍历数据,将遍历的数据存储到另外一个起来,相比上一个算法步骤减少很多
7.rotate 将元素按某个中间值进行互换
template<class ForwardIterator1, class ForwardIterator2>
void _iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
typename std::iterator_traits<ForwardIterator1>::value_type tmp = *a;
*a = *b;
*b = tmp;
}
template<class ForwardIterator>
void roate(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
{
for (ForwardIterator i = middle;;)
{
_iter_swap(first,i);
first++;
i++;
if (first == middle)
{
if (i == last)
{
return;
}
else
{
middle = i;
}
}
else if(i == last)
{
i = middle;
}
}
}
int main()
{
std::ostream_iterator<int> outite(std::cout," ");
int ia[6] = { 1,2,3,4,5,6 };
std::vector<int> iv(ia, ia+6);
roate(iv.begin(),iv.begin() +3, iv.end());
return 0;
}
将数据进行通过中间值进行旋转,采用交换的算法。同时考虑:1.数据等长 2.数据前长后短 3.数据前短后长。
7.1.rotate 将元素按某个中间值进行互换
template<class ForwardIterator>
void _roate(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
{
std::reverse(first, middle);
std::reverse(middle, last);
std::reverse(first, last);
}
int main()
{
std::ostream_iterator<int> outite(std::cout," ");
int ia[6] = { 1,2,3,4,5,6 };
std::vector<int> iv(ia, ia+6);
_roate(iv.begin(),iv.begin()+4, iv.end());
return 0;
}
根据迭代器的作用,此方法更简单,通过对两段数据的逆转,之后在对整个数据进行逆转,就可以达到效果
8.roate_copy 将元素按某个中间值进行互换
template<class ForwardIterator,class OutputIterator>
void roate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result)
{
copy(first, middle,copy(middle,last, result));
}
int main()
{
int ia[6] = { 1,2,3,4,5,6 };
std::vector<int> iv(ia, ia+6);
std::vector<int> vecResult;
_roate(iv.begin(),iv.begin()+4, iv.end());
vecResult.resize(6);
roate_copy(iv.begin(), iv.begin() + 4, iv.end(), vecResult.begin());
return 0;
}
通过拷贝操作,将后一段信息拷贝到另外一个空间的前端,在拷贝前一段信息
9.search 判断是否包含子串
template<class ForwardIterator>
typename std::iterator_traits<ForwardIterator>::difference_type USD_distance(ForwardIterator first,ForwardIterator last)
{
typename std::iterator_traits<ForwardIterator>::difference_type n = 0;
while (first != last)
{
++first;
++n;
}
return n;
}
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 USD_search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
{
typename std::iterator_traits<ForwardIterator1>::difference_type d1 = 0;
d1 = USD_distance(first1, last1);
typename std::iterator_traits<ForwardIterator2>::difference_type d2 = 0;
d2 = USD_distance(first2, last2);
if (d1 < d2)
{
return last1;
}
ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2;
while (current2 != last2)
{
if (*current2 == *current1)
{
++current1;
++current2;
}
else
{
if (d1 == d2)
{
return last1;
}
current1 = ++first1;
current2 = first2;
d1--;
}
}
return first1;
}
int main()
{
int ia[6] = { 1,2,3,4,5,6 };
std::vector<int> iv(ia, ia+6);
int iav[3] = {4,5,6 };
std::vector<int> ivec(iav, iav + 3);
std::vector<int>::iterator item = USD_search(iv.begin(), iv.end(), ivec.begin(), ivec.end());
return 0;
}
遍历子串,判断子串每个元素是否等于目标串中的值 当有不相等的值时,目标串开始位置前进一格,重新开始遍历子串,以此往复。
10.search_n 查找n个满足条件的元素所组成的子串
template<class T>
class USD_greater
{
public:
USD_greater()
{
}
bool operator()(T leftValue, T rightValue)
{
if (leftValue > rightValue)
{
return true;
}
return false;
}
};
template<class ForwardIterator, class Integer,class T,class pred>
ForwardIterator USD_search_n(ForwardIterator first, ForwardIterator last, Integer count,const T& value, pred binary_pred)
{
if (count < 0)
{
return first;
}
else
{
while (first != last)
{
if (binary_pred(*first,value))
{
break;
}
first++;
}
while (first != last)
{
Integer n = count - 1;
ForwardIterator i = first;
++i;
while (i != last && n > 0 && binary_pred(*i, value))
{
--n;
++i;
}
if (n == 0)
{
return first;
}
else
{
while (i != last)
{
if (binary_pred(*i, value))
{
break;
}
i++;
}
}
first = i;
}
}
}
int main()
{
int ia[7] = { 1,2,3,4,3,5,6 };
std::vector<int> iv(ia, ia+7);
std::vector<int>::iterator item = USD_search_n(iv.begin(), iv.end(),2,3, USD_greater<int>());
return 0;
}
通过遍历数据,查找到符合条件的第一个元素。在此位置进行遍历,查找n个元素是否相等。若不满足条件,查找下一个符合条件的第一个元素
11.swap_ranges 等长区间的元素进行互换
template<class ForwardIterator1, class ForwardIterator2>
void _iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
typename std::iterator_traits<ForwardIterator1>::value_type tmp = *a;
*a = *b;
*b = tmp;
}
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 USD_swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
{
for (; first1 != last1; ++first1, ++first2)
{
iter_swap(first1, first2);
}
return first2;
}
int main()
{
int ia[7] = { 1,1,1 };
std::vector<int> iv(ia, ia+3);
int iav[3] = {4,5,6 };
std::vector<int> ivec(iav, iav + 3);
std::vector<int>::iterator item = USD_swap_ranges(iv.begin(), iv.end(), ivec.begin());
return 0;
}
遍历数据,将两个串的数据,通过交换函数,将两个值进行对换。
12.transform 提供的仿函数用于区间每个元素
template<class T>
class multiply
{
public:
multiply(int value)
{
m_value = value;
}
T operator()(int value)
{
return value = m_value * value;
}
private:
T m_value;
};
template<class InputIterator, class OutputIterator,class UnaryOperation>
OutputIterator USD_transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op)
{
for (; first != last; ++first, ++result)
{
*result = op(*first);
}
return first;
}
//第二个版本,处理方式,前后两个数据进行处理,将所得到的结果存储起来。(与上一个版本相比,只是仿函数多了一个参数)
template<class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator USD_transform(InputIterator first, InputIterator last, InputIterator first2, OutputIterator result, BinaryOperation Binary_op)
{
for (; first != last; ++first, ++first2, ++result)
{
*result = Binary_op(*first, *first2);
}
return first;
}
int main()
{
int ia[3] = { 1,2,3 };
std::vector<int> iv(ia, ia+3);
std::vector<int> ivec;
ivec.resize(3);
USD_transform(iv.begin(), iv.end(), ivec.begin(), multiply<int>(2));
return 0;
}
遍历数据,将数据通过仿函数进行处理。可用于处理集合中的所有数据。
13.adjacent_find 查找相邻的重复元素
template<class ForwardIterator>
ForwardIterator USD_adjacent_find(ForwardIterator first, ForwardIterator last)
{
if (first == last)
{
return last;
}
ForwardIterator next = first;
while (++next != last)
{
if (*first == *next)
{
return first;
}
first = next;
}
return last;
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int>::iterator item = USD_adjacent_find(iv.begin(), iv.end());
return 0;
}
元素重复,即判断两个相邻的元素是否相等。判断第一个元素和第二个元素是否相等,不相等,将第二个元素,作为首元素,将下一个元素作为第二个元素两者相比,以此类推。
14.unique 移除相邻的重复元素(并不删除空间)
template<class ForwardIterator>
ForwardIterator USD_adjacent_find(ForwardIterator first, ForwardIterator last)
{
if (first == last)
{
return last;
}
ForwardIterator next = first;
while (++next != last)
{
if (*first == *next)
{
return first;
}
first = next;
}
return last;
}
template<class InputIterator,class OutputIterator>
OutputIterator USD_unique_copy(InputIterator first, InputIterator last, OutputIterator result)
{
if (first == last)
{
return result;
}
typename std::iterator_traits<InputIterator>::value_type value = *first;
*result = value;
while (++first != last)
{
if (value != *first)
{
value = *first;
*++result = value;
}
}
return result;
}
template<class ForwardIterator>
ForwardIterator USD_unique(ForwardIterator first, ForwardIterator last)
{
first = USD_adjacent_find(first,last);
return USD_unique_copy(first,last, first);
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int>::iterator item = USD_adjacent_find(iv.begin(), iv.end());
USD_unique(iv.begin(), iv.end());
std::vector<int> ivec;
ivec.resize(5);
//USD_unique_copy(iv.begin(), iv.end(), ivec.begin());
return 0;
}
此算法的设计主要依靠unique_copy(),该算法的逻辑:记录第一个值,判断与下一个值是否相等。如果相等跳过,进行下一个数据的比较。如果数据不相等,记录数据在结果中,同时更新比较的值为当前数据的值。(注意:此函数,也是通过改写内容来达到删除数据的效果)
15.count 查找某个元素的个数
template <class InputIterator,class T>
typename std::iterator_traits<InputIterator>::difference_type USD_count(InputIterator first, InputIterator last, const T& value)
{
typename std::iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; first++)
{
if (value == *first)
{
n++;
}
}
return n;
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
int n = USD_count(iv.begin(), iv.end(), 2);
return 0;
}
此算法通过遍历数据,统计满足条件的数据个数
16.count_if 查找某个元素的个数
template<class T>
class compere
{
public:
compere()
{
}
bool operator()(T Value)
{
if (Value > 2)
{
return true;
}
return false;
}
};
template <class InputIterator, class Predicate>
typename std::iterator_traits<InputIterator>::difference_type USD_count_if(InputIterator first, InputIterator last, Predicate pred)
{
typename std::iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; first++)
{
if (pred(*first))
{
n++;
}
}
return n;
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int>::iterator item = USD_adjacent_find(iv.begin(), iv.end());
//USD_unique(iv.begin(), iv.end());
int n = USD_count_if(iv.begin(), iv.end(), compere<int>());
return 0;
}
此算法通过遍历数据,统计满足条件的数据个数。与count相比,只是将条件封装成了仿函数,可通过仿函数满足自己的条件
17.find 查找某个元素返回一个迭代器
template<class InputIterator,class T>
InputIterator USD_find(InputIterator first, InputIterator last, const T& value)
{
while (first != last && *first != value)
{
++first;
}
return first;
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int>::iterator item = USD_find(iv.begin(), iv.end(),3);
return 0;
}
此算法通过遍历数组,不满足条件时继续遍历数据。满足条件时,返回指向这个数据的迭代器
18.find_if 查找某个元素返回一个迭代器
template<class T>
class compere
{
public:
compere()
{
}
bool operator()(T Value)
{
if (Value > 2)
{
return true;
}
return false;
}
};
template<class InputIterator,class Predicate>
InputIterator USD_find_if(InputIterator first, InputIterator last, Predicate pred)
{
while (first != last && !pred(*first))
{
++first;
}
return first;
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int>::iterator item = USD_find_if(iv.begin(), iv.end(), compere<int>());
return 0;
}
此算法通过遍历数组,不满足条件时继续遍历数据。满足条件时,返回指向这个数据的迭代器。相比上一个算法,这里将条件封装成了迭代器,用户可自定义条件。
19.find_end 查找完全匹配的子串最后出现的位置
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 USD_find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2 == last2)
{
return last1;
}
else
{
ForwardIterator1 result = last1;
while (1)
{
ForwardIterator2 new_result = USD_search(first1,last1,first2,last2);
if (new_result == last1)
{
return result;
}
else
{
result = new_result;
first1 = new_result;
++first1;
}
}
}
}
int main()
{
int ia[5] = { 1,2,2,2,3 };
std::vector<int> iv(ia, ia+5);
std::vector<int> ivec;
ivec.push_back(2);
ivec.push_back(2);
std::vector<int>::iterator item = USD_find_end(iv.begin(), iv.end(), ivec.begin(), ivec.end());
for (; item != iv.end(); item++)
{
printf("%d\n", *item);
}
return 0;
}
此函数的核心思想,首先查找子串的位置。若查找到子串,将查找的开始位置移动到此位置的下一个位置。同时记录此位置,如果没查找到,就返回上一个记录的位置。
20.find_first_of 查找目标区的元素在源区第一次出现的位置
template<class InputIterator, class ForwardIterator>
InputIterator USD_find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2)
{
for (; first1 != last1; ++first1)
{
for (ForwardIterator iter = first2; iter != last2; ++iter)
{
if (*first1 == *iter)
{
return first1;
}
}
}
return last1;
}
int main()
{
int ia[5] = { 1,2,3,4,5 };
std::vector<int> iv(ia, ia+5);
std::vector<int> ivec;
ivec.push_back(4);
ivec.push_back(5);
std::vector<int>::iterator item = USD_find_first_of(iv.begin(), iv.end(), ivec.begin(), ivec.end());
for (; item != iv.end(); item++)
{
printf("%d\n", *item);
}
return 0;
}
此算法由两个for() 循环完成,整体逻辑遍历源区的每一个元素与目标区的每一个元素对比。当第一次满足条件时,返回指向源区的迭代器
21.for_each 遍历数据
template<class InputIterator, class Function>
Function USD_for_each(InputIterator first, InputIterator last, Function f)
{
for (; first != last; ++first)
{
f(*first);
}
return f;
}
此算法,主要为遍历数据,处理逻辑存放在仿函数中。通过修改仿函数来达到自己的需求。
22. generate 将仿函数运行的结果填入源区间元素中
template<class ForwardIterator, class Generator>
ForwardIterator USD_generate(ForwardIterator first, ForwardIterator last, Generator gen)
{
for (; first != last; ++first)
{
*first = gen();
}
return first;
}
遍历元素,通过仿函数计算的值填入到元素中
23. generate_n 运算结果填写到从迭代器开始的n个元素身上
template<class ForwardIterator,class size, class Generator>
ForwardIterator USD_generate_n(ForwardIterator first, ForwardIterator last, size n, Generator gen)
{
for (; n>0; --n,++first)
{
*first = gen();
}
return first;
}
与上一个函数类似,只是控制了填写的个数和开始的位置
24. includes (应用有序区间),验证目标集合是否为源集合的子集
template<class T>
class USD_less
{
public:
USD_less()
{
}
bool operator()(T leftValue, T rightValue)
{
if (leftValue < rightValue)
{
return true;
}
return false;
}
};
template<class InputIterator1, class InputIterator2,class compare>
bool USD_includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, compare comp)
{
while (first1 != last1 && first2 != last2)
{
if (comp(*first2, *first1))
{
return false;
}
else if (comp(*first1, *first2))
{
first1++;
}
else
{
first1++;
first2++;
}
}
return first2 == last2;
}
int main()
{
int ia[5] = { 1,2,3,4,5 };
std::vector<int> iv(ia, ia+5);
std::vector<int> ivec;
ivec.push_back(4);
ivec.push_back(5);
bool bvalue = USD_includes(iv.begin(), iv.end(), ivec.begin(), ivec.end(), USD_less<int>());
ivec.push_back(6);
bvalue = USD_includes(iv.begin(), iv.end(), ivec.begin(), ivec.end(), USD_less<int>());
return 0;
}
遍历集合,将源集合和目标集合取出数据一一对比。源集合数据小于目标集合数据时
,源集合数据查找下一个。当相等时,源集合和目标集合统一下一个数据。当源集合遍历结束时,判断目标集合是否遍历完,若遍历完,则目标集合属于原集合的子集。
25. max_element 返回一个指向最大元素的迭代器
template<class ForwardIterator, class compare>
ForwardIterator USD_max_element(ForwardIterator first, ForwardIterator last, compare comp)
{
if (first == last)
{
return first;
}
ForwardIterator result = first;
while (++first != last)
{
if (comp(*result,*first))
{
result = first;
}
}
return result;
}
通过循环查找最大的值,并将结果返回
26. merge(应用有序区间)将两个排序的集合存放在另一个空间中
template<class T>
class USD_less
{
public:
USD_less()
{
}
bool operator()(T leftValue, T rightValue)
{
if (leftValue < rightValue)
{
return true;
}
return false;
}
};
template<class InputIterator1, class InputIterator2,class OutputIterator,class compare>
OutputIterator USD_merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, compare comp)
{
while (first1 != last1 && first2 != last2)
{
if (comp(*first1, *first2))
{
*result = *first1;
first1++;
}
else
{
*result = *first2;
first2++;
}
result++;
}
copy(first1, last1, copy(first2, last2,result));
return result;
}
int main()
{
int ia[5] = { 1,2,3,4,5 };
std::vector<int> iv(ia, ia+5);
std::vector<int> ivec;
ivec.push_back(2);
ivec.push_back(5);
ivec.push_back(6);
std::vector<int> vecResult;
vecResult.resize(8);
USD_merge(iv.begin(), iv.end(), ivec.begin(), ivec.end(), vecResult.begin(), USD_less<int>());
return 0;
}
同时遍历两个集合数据,将两个集合中的数据比较,根据满足的条件,分别移动不同集合中的数据。当遍历结束后,其中一个集合必为空集。另外一个集合中剩余的数据,满足放在最后的需求。通过组合使用copy操作,将剩余的数据,拷贝到结果中。
27. min_element 返回一个指向最小值的迭代器
template<class ForwardIterator, class compare>
ForwardIterator USD_min_element(ForwardIterator first, ForwardIterator last, compare comp)
{
if (first == last)
{
return first;
}
ForwardIterator result = first;
while (++first != last)
{
if (comp(*result, *first))//result 小于first时,返回true
{
result = first;
}
}
return result;
}
与max_element算法逻辑一样,关键点在于封装的仿函数不同。
28. partition 区间内的集合,判断为true的放前面,判断为false放后面
template<class T>
class USD_LessThan
{
public:
USD_LessThan()
{
}
bool operator()(T Value)
{
if (Value > 4)
{
return true;
}
return false;
}
};
template<class ForwardIterator1, class ForwardIterator2>
void _iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
typename std::iterator_traits<ForwardIterator1>::value_type tmp = *a;
*a = *b;
*b = tmp;
}
template<class BidircetionalIterator,class Predicate>
BidircetionalIterator USD_partition(BidircetionalIterator first, BidircetionalIterator last, Predicate pred)
{
while (true)
{
while (true)
{
if (first == last)
{
return first;
}
if (pred(*first))
{
++first;
}
else
{
break;
}
}
--last;
while (true)
{
if (first == last)
{
return first;
}
if (!pred(*last))
{
--last;
}
else
{
break;
}
}
_iter_swap(first,last);
++first;
}
}
int main()
{
int ia[9] = { 1,2,3,4,5,6,7,8,9 };
std::vector<int> iv(ia, ia+9);
USD_partition(iv.begin(), iv.end(), USD_LessThan<int>());
return 0;
}
此函数,通过前后遍历数据,从开始端遍历数据,结果为true的移动数据到下一个。结果为false的不移动,与从末端开始逆序遍历的数据,判断结果为true的进行数据交换。即达到预期的效果。
29. remove 删除指定元素(并不删除空间)
template<class InputIterator,class OutputIterator,class T>
OutputIterator USD_remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value)
{
while (first != last)
{
if (*first != value)
{
*result = *first;
++result;
}
first++;
}
return result;
}
template<class ForwardIterator,class T>
ForwardIterator USD_remove(ForwardIterator first, ForwardIterator last, const T& value)
{
first = std::find(first,last,value);
ForwardIterator next = first;
return first == last ? last : USD_remove_copy(++next,last,first, value);
}
int main()
{
int ia[9] = { 5,2,5,4,5,6,7,5,9 };
std::vector<int> iv(ia, ia+9);
USD_remove(iv.begin(), iv.end(),5);
return 0;
}
此函数,首先通过find找到第一个出现的元素,调用remove_copy,将之后非的删除元素,复制到查找的位置。通过复制粘贴的操作,来达到删除的效果。
30. remove_copy 删除指定元素,结果存放在另外一个空间
template<class InputIterator,class OutputIterator,class T>
OutputIterator USD_remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value)
{
while (first != last)
{
if (*first != value)
{
*result = *first;
++result;
}
first++;
}
return result;
}
通过遍历集合,将不是指定元素的值存放在另一个空间中。
31. remove_if remove_copy_if 删除区间内,被仿函数评估为true的元素
template<class InputIterator,class OutputIterator,class Predicate>
OutputIterator USD_remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate Pred)
{
while (first != last)
{
if (!Predicate(*first))
{
*result = *first;
++result;
}
first++;
}
return result;
}
template<class ForwardIterator,class Predicate>
ForwardIterator USD_remove_if(ForwardIterator first, ForwardIterator last, Predicate Pred)
{
first = std::find_if(first,last,Pred);
ForwardIterator next = first;
return first == last ? last : USD_remove_copy_if(++next,last,first, Pred);
}
与之前的函数相比,只是将判断条件封装为了仿函数,来满足用户的需求。
总结
总结出来的这些函数,只占STL算法的一部分,只是用来单纯的数据处理。纵观上述函数内部的实现都很简单,也是日常经常会手动开发的功能。在此进行函数总结,避免日后工作内容的重复开发。后续内容在持续更新中。。。。