STL算法详细解剖——单纯数据处理函数
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算法的一部分,只是用来单纯的数据处理。纵观上述函数内部的实现都很简单,也是日常经常会手动开发的功能。在此进行函数总结,避免日后工作内容的重复开发。后续内容在持续更新中。。。。