STL算法详细解剖——单纯数据处理函数

STL算法详细解剖——单纯数据处理函数

前言

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

相关序列文章

STL —heap算法源码刨析 make_heap、push_heap、pop_heap、sort_heap操作分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值