c++ algorithm(1)

版权声明:请多多指教 https://blog.csdn.net/arctic_fox_cn/article/details/81139919
C++ algorithm 中的部分方法的用法

一般情况下,algorithm 中的操作不是针对于对象本身而是迭代器

首先查看了algorithm 头文件 ps:(gcc)

#ifndef _GLIBCXX_ALGORITHM
#define _GLIBCXX_ALGORITHM 1

#pragma GCC system_header

#include <utility> // UK-300.
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>

#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithm>
#endif

#endif /* _GLIBCXX_ALGORITHM */

之后查看了bits/algorithmfwd.h

#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1

#pragma GCC system_header

#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /*
    adjacent_find
    all_of (C++0x)
    any_of (C++0x)
    binary_search
    copy
    copy_backward
    copy_if (C++0x)
    copy_n (C++0x)
    count
    count_if
    equal
    equal_range
    fill
    fill_n
    find
    find_end
    find_first_of
    find_if
    find_if_not (C++0x)
    for_each
    generate
    generate_n
    includes
    inplace_merge
    is_heap (C++0x)
    is_heap_until (C++0x)
    is_partitioned (C++0x)
    is_sorted (C++0x)
    is_sorted_until (C++0x)
    iter_swap
    lexicographical_compare
    lower_bound
    make_heap
    max
    max_element
    merge
    min
    min_element
    minmax (C++0x)
    minmax_element (C++0x)
    mismatch
    next_permutation
    none_of (C++0x)
    nth_element
    partial_sort
    partial_sort_copy
    partition
    partition_copy (C++0x)
    partition_point (C++0x)
    pop_heap
    prev_permutation
    push_heap
    random_shuffle
    remove
    remove_copy
    remove_copy_if
    remove_if
    replace
    replace_copy
    replace_copy_if
    replace_if
    reverse
    reverse_copy
    rotate
    rotate_copy
    search
    search_n
    set_difference
    set_intersection
    set_symmetric_difference
    set_union
    shuffle (C++0x)
    sort
    sort_heap
    stable_partition
    stable_sort
    swap
    swap_ranges
    transform
    unique
    unique_copy
    upper_bound
    ......

​ 上面这些应该是algoritm库中可以使用的函数,简单看了这个头文件里的部分函数之后以及用法,之后就开始了学习这部分知识的部分内容(伴随着C++primer)。

1、find()

​ 在我们写程序的时候,经常会遇到查询某个元素是否在某一个块内,那么我们就可以使用find()这个方法,它的操作对象是迭代器。如果它查询的关键字或者是值存在这个块内,返回元素的迭代器,如果不存在返回尾部迭代器(cbegin())。

用法:

//这部分内容来自于bits/algorithmfwd.h 
// find

  template<typename _FIter1, typename _FIter2>
    _FIter1
    find_end(_FIter1, _FIter1, _FIter2, _FIter2);

  template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
    _FIter1
    find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);

  // find_first_of
  // find_if

#if __cplusplus >= 201103L
  template<typename _IIter, typename _Predicate>
    _IIter
    find_if_not(_IIter, _IIter, _Predicate);
#endif
            .....

    template<typename _IIter, typename _Tp>
    _IIter 
    find(_IIter, _IIter, const _Tp&);

  template<typename _FIter1, typename _FIter2>
    _FIter1
    find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);

  template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
  //Binary predicate 二元谓词 用户自定义的或者标准库中的
    _FIter1
    find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);

  template<typename _IIter, typename _Predicate>
    _IIter
    find_if(_IIter, _IIter, _Predicate);

例子:

   vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
   string filename;
   if(find(fname.cbegin(),fname.cend(),"alibaba")!=fname.cend())
   cout<<"alibaba  在这里!!"<<endl;


    //现在迭代器指向的是谁?

    cout<<"NOW :"<<*find(fname.cbegin(),fname.cend(),"alibaba")<<endl;
    //输出:   NOW :alibaba

2、find_first_of()

​ 作用:查找一个对象迭代范围内,另一个对象迭代范围内的某一个元素。

​ 我运用这个函数,发现他会先根据要查找的迭代范围内的元素[依次 依次 依次]进行判断是否在传来的迭代范围内。

扫描二维码关注公众号,回复: 3085252 查看本文章

例如:

vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
list<string>fname1{"liubei","wangwei","nalanxingde","ins","alibaba"};
auto re=find_first_of(fname.cbegin(),fname.cend(),fname1.cbegin(),fname1.cend());
if(re!=fname.cend())
cout<<*re<<" 在这里!"<<endl;

​ 无论我如何改变fname1中元素位置,它都会先从fname中选择一个元素进行查找,查找顺序google->alibaba->baidu->facebook->mi->ins.如果google 存在fname1中直接返回指向google的迭代器,如果没有查找alibaba,反复进行这几步,如果都没有返回尾部迭代器。

3、find_if()与find_if_not()

​ 作用:

​ find_if(): 查找与给定谓词对其返回True的元素;

​ find_if_not(): 查找与给定谓词对其返回False的元素;

4、accumulate求和

这个函数它存在于numeric头文件中,其中我查看了bits/stl_numeric.h

    template<typename _InputIterator, typename _Tp>
    inline _Tp
    accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);

      for (; __first != __last; ++__first)
    __init = __init + *__first;
      return __init;
    }


template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
    inline _Tp
    accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
           _BinaryOperation __binary_op)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);

      for (; __first != __last; ++__first)
    __init = __binary_op(__init, *__first);
      return __init;
    }

例如:

 list<int> num{1,2,3,4,5,6,10,22,11,333};
    //设置num初始和为0
   cout<<"num 中元素的和为: "<<accumulate(num.cbegin(),num.cend(),0)<<endl;
   //设置num初始和为100
   cout<<"num 中元素的和为: "<<accumulate(num.cbegin(),num.cend(),100)<<endl;

/*输出: num 中元素的和为: 397
 *      num 中元素的和为: 497
 */

其中 accumulate 第三个参数 可以定义 这个“求和“运算规则和返回类型

例如:

cout<<"name:"<<accumulate(next(fname.cbegin()),fname.cend(),string(fname[0]),[](string a, string b) {return a + '-' + b;})<<endl;

//输出:name:google-alibaba-baidu-facebook-mi-ins

5、equal比较两个序列是否保存相同的值

用法: equal(A.cbegin(),A.cend(),B.cbegin());

​ 由于接受一个单一的迭代器表示另一个序列,所以编译器假设第二个容器至少与第一个序列大长度相同,那么就意味着如果第二个如果小于第一个迭代器会把后面不属于第二个序列的元素也当作是第二个的。

例如:

 vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
 vector<string>fname1{"liubei","wangwei","nalanxingde","ins","alibaba"};
 auto fsize=fname.size();
   fname1.resize(fsize);
   auto be=equal(fname.cbegin(),fname.cend(),fname1.cbegin());
   if(be)
     cout<<"两个具有相同的。"<<endl;
   else
     cout<<"两个不同。"<<endl;
     cout<<"fname size="<<fsize<<"\tfname1 size="<<fname1.size()<<endl;


/*输出:
两个不同。
fname size=6    fname1 size=6
*/

6、fill 相关操作

​ 作用: 相容器内部填充值,如果填充的大小大于原容器大小,需要引入插入迭代器,因为算法不会对对象本身进行改变。

​ 用法:

​ fill(iter_1,iter_2,value);

ADD:back_inserter 插入迭代器 需要引入 iterator 头文件

​ 作用:向容器插入元素的迭代器。

用法:fill_n(back_inserter(fname),100,string(“bigboom”));

例如:

fill_n(back_inserter(fname),100,string("bigboom"));
cout<<"fname size="<<fname.size()<<endl;
cout<<"fname end="<<fname[105]<<endl;

//output :  fname size= 106
//fname end=bigboom

如果改变vector容量的话,进行fill_n操作还是无效的;

7、copy 拷贝操作

​ 作用:接受一个范围序列,把这个范围序列传递给第三个范围序列;

​ 用法:copy(iter_1,iter_2,iter_3);

例如:

 copy(fname1.cbegin(),fname1.cend(),ostream_iterator<string>(cout," "));
//output:liubei wangwei nalanxingde ins alibaba

8、replace和replace_copy操作

​ 作用:

​ replace:四个参数,接受一个范围,在接受两个参数,一个为需要修改的值,一个是修改后的值;

​ replace_copy:五个参数,多一个迭代器,该迭代器的作用是,原来容器里的序列不会改变,而是将改变之后的序列copy到另一个容器当中;

​ 用法:repalce(iter_1,iter_2,value_1,value_2);

​ repalce_copy(ietr_1,iter_2,back_inserter(vec),value_1,value_2);

例如:

        copy(fname1.cbegin(),fname1.cend(),ostream_iterator<string>(cout," "));
       cout<<endl;
       replace(num.begin(),num.end(),1,100);
        copy(num.cbegin(),num.cend(),ostream_iterator<int>(cout," "));
        cout<<endl;
       vector<int> vec;
        replace_copy(num.begin(),num.end(),back_inserter(vec),100,101);
        copy(num.cbegin(),num.cend(),ostream_iterator<int>(cout," "));
        cout<<endl;
        copy(vec.cbegin(),vec.cend(),ostream_iterator<int>(cout," "));
        cout<<endl;

猜你喜欢

转载自blog.csdn.net/arctic_fox_cn/article/details/81139919