Accelerated C++笔记 第6章

Chapter 6

 

<algorithm>

The header <algorithm> defines a collection offunctions especially designed to be used onranges of elements.

更多算法:http://www.cplusplus.com/reference/algorithm/

泛型算法std::copy()

    泛型算法指不属于任何特定类别容器的算法。

    前面第五章中

    ret.insert (ret.end(), bottom.begin(), bottom.end() );

    的替代版本是

    copy ( bottom.begin(),bottom.end(), back_inserter( ret ) );

        copy接受三个迭代器,并一次一个的将半开区间【first second)中的元素赋值给third迭代器指向的元素,

        然后++first ++third

std::back_inserter() //<iterator>

是一种迭代器适配器函数,可以看作是一种特殊的输出迭代器,允许那些通常是覆盖元素的算法(如copy)变为自动在容器末尾插入新元素。

另外,back_inserter()要求参数是拥有push_back()成员的容器(如,vector,deque, list).

下面两种写法等价:

std::back_insert_iterator<vector<int> > it =std::back_inserter(vi);

*it = 88;

//等价于

vi.push_back(88 );

 

*third++ = *first++

*++优先级相同,且都是右结合的,因此*first++ 就是 *first++

故上式等价于:{*third= *first; ++third; ++first;}

 

std::find_if

Find element in range

对函数的理解可参考这段代码:


1
2
3
4
5
6
7
8
9
template < class  InputIterator,  class   UnaryPredicate>
InputIterator find_if  (InputIterator first, InputIterator last, UnaryPredicate pred)
{
     while  (first!=last) {
       if  (pred(*first))  return  first;
       ++first;
     }
     return  last;
}


   相应的可以比较一下find函数的等价代码:


1
2
3
4
5
6
7
8
9
template < class  InputIterator,  class  T>
InputIterator find (InputIterator  first, InputIterator last,  const  T& val)
{
       while  (first!=last) {
         if  (*first==val)  return  first;
         ++first;
       }
       return  last;
}



回文

1
2
3
4
bool  is_palindrome( const  string& s)
{
     return  std::equal(s.begin(), s.end(), s.rbegin());
}

std::equal()

测试两个范围内的元素是否相等,第三个参数是第二个序列的初始位置。

rbegin()

返回指向最后一个元素的反向迭代器。

 

std::transform()

等价代码:

1
2
3
4
5
6
7
8
9
10
template  < class  InputIterator,  class  OutputIterator,  class   UnaryOperator>
OutputIterator transform  (InputIterator first1, InputIterator last1,
                                  OutputIterator result, UnaryOperator op)
{
       while  (first1 != last1) {
         *result = op(*first1);   // or:  *result=binary_op(*first1,*first2++);
         ++result; ++first1;
       }
       return  result;
}

std::accumulate() //<numeric>

Accumulate values in range


1
2
3
4
5
6
7
8
9
template  < class  InputIterator,  class  T>
T accumulate (InputIterator  first, InputIterator last, T  init) //注意第三个参数的类型决定返回值类型
{
       while  (first!=last) {
         init = init + *first; 
         ++first;
       }
       return  init;
}


 std::remove_copy()

把除去值为指定值的剩余所有元素复制到指定目的地。

1
2
3
4
5
6
7
8
9
10
11
12
13
template  < class  InputIterator,  class  OutputIterator,  class  T>
OutputIterator remove_copy  (InputIterator first, InputIterator last,
                                    OutputIterator result,  const  T& val)
{
       while  (first!=last) {
         if  (!(*first == val)) {
           *result = *first;
           ++result;
         }
         ++first;
       }
       return  result;
}

相应的有:remove_copy_if

 

std::remove_if() / std::remove()

把不满足remove谓词条件的移动(对那些满足remove条件的直接覆盖)到序列开头,返回新的end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template   < class  ForwardIterator,  class  UnaryPredicate>
ForwardIterator remove_if  (ForwardIterator first, ForwardIterator last,
                                UnaryPredicate pred)
{
    ForwardIterator result =  first;
    while  (first!=last) {
      if   (!pred(*first)) {
        *result = *first;
        ++result;
      }
      ++first;
    }
    return  result; //result是最后一个不被删除的元素后面的那个位置
}

remove()并不会改变容器的长度,删除元素可以使用erase+remove

1
students.erase(remove_if ( students.begin(), students.end(), fgrade ), students.end() );

 

std::stable_partition() / std::partition()

对序列重新排列,谓词为true的排在前面,stable版本会保持原先的排列顺序。

返回true组的end(false组的第一个元素)。

 

以函数作为另一个函数的参数

1
2
3
4
5
6
7
8
9
10
11
int  foo( int  x)
{
     returnx*x;
}
void  use_foo(intx,  int  f( int ))    //参数类似于函数声明
{
     std::cout<< f(x) + x << std::endl;
}
……
use_foo(2, foo);
……

//来自chapter 10 的深入讲解


use_foo中的参数 int f( int ) 事实上会被编译器转化成一个指向这种类型函数的指针。因此这一参数也可以等价地写成:int ( *f )( int ) //意指 f 是指向具有一个int类型参数并返回int类型结果的函数的指针。


另一方面,use_foo( 2, foo ); 则会被编译器解释为 use_foo ( 2, &foo ); //我们也可以等价的这样写。


即传参时实际执行了 f = &foo; 的操作。//就像普通指针的用法一样。


也可以认为编译器会把 f = foo; 理解为 f = &foo; (编译器自动将函数名转化成指向函数的指针)


再另一方面,我们在use_foo函数中写 f(x),这实际上应该写成(*f)(x)//就像普通指针的用法一样。


二者都没问题是因为编译器自动认为二者是等价的。(编译器将对函数指针的调用自动地解释成对该指针指向函数的调用


返回函数指针的函数


有两种写法:


1.


typedef int (*type_f)(int);


type_f get_foo_ptr();


2.


int ( *get_foo_ptr() ) (int);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值