effective stl读书笔记 & stl里面提供的算法 & emplace & ostream_iterator

加锁和解锁,也可以在构造函数和析构函数里面,自动调用。

 

相等和等价的关系:等价是用在排序的时候,跟less函数有关。

 

vector,deque,string 要用erase-remove组合;而关联容器,直接erase就可以了。

 

copy(x.begin(), x.end(), ostream_iterator<string>(cout, "\n"));

但是如果x的类型是string*,就不行。

 

自定义一个print(const string*ps);

然后 for_each(x.begin(), x.end(), print);

 

或者

struct Dereference{

template<typename T>

const T& operator()(const T* ptr)const {

return *ptr;

}

}

 

transform(x.begin(), x.end(),

ostream_iterator<string>(cout, "\n"),

Dereference());

 

注意transform的两种形式:

template < class InputIterator, class OutputIterator, class UnaryOperator >
  OutputIterator transform ( InputIterator first1, InputIterator last1,
                             OutputIterator result, UnaryOperator op );

template < class InputIterator1, class InputIterator2,
           class OutputIterator, class BinaryOperator >
  OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, OutputIterator result,
                             BinaryOperator binary_op );


有如下两个使用原型,一个将迭代器区间[first,last)中元素,执行一元函数对象op操作,交换后的结果放在[result,result+(last-first))区间中。另一个将迭代器区间[first1,last1)的元素*i,依次与[first2,first2+(last-first))的元素*j,执行二元函数操作binary_op(*i,*j),交换结果放在[result,result+(last1-first1))。

 

set的比较类型,是less_equal,注意语义里面带了equal。

可以我看cplusplus网站上面定义的是less。

那还是以less为准吧。

http://www.cplusplus.com/reference/set/set/set/

 

用advance和distance可以把const iterator 转换成 iterator

其实是这样,iterator i = x.begin(); ci是const iterator

那么 advance(i, distance(i, ci));也就是把 i 移动到 ci 的位置。

 

对于 reverse_iterator类型,有一个base函数,能够返回对应的正向iterator信息,因为有的函数只支持正向iterator.

但是这个base返回的iterator,只能在insert的时候用,因为指向的reverse那个方向的前一个节点。

对于erase的时候,就不能用了,因为和reverse的指的不是一个节点。

 

算法

transform 很多地方都能够用到。

但是一定要注意,result的空间要大于等于待放入的内容。不然结果未定义。

比如:

尾部加入,用back_inserter

result.reserve(result.size()+values.size());

transform(value.begin(), value.end(),

back_inserter(result),

transfunc);

 

如果需要覆盖

if (result.size() < value.size()) {

  result.resize(value.size())

}

transform(value.begin(), value.end(),

result.begin(),

transfunc);

 

 

partial_sort对于头部排序,很好用。

partial_sort(w.begin(), w.begin()+20, w.end(), comp);

 

而如果前面20个也不关心顺序,那么用

nth_element

用法:

nth_element(w.begin(), w.begin()+19, w.end(), comp);

 

partial_sort是不稳定的,nth_element,sort也没有提供稳定性

 

partition函数用来分隔的。注意,partition是快排很好的工具,但是stl里面的partition因为第三个参数是一个bool函数,所以在快排的时候,不太好用。

bool函数为true的,放在partition的前面。

bool isOdd(int i) {return (i%2)==1;}

int ir[] = {6, 9, 10, 12, 7, 8};
vector<int> x(ir, ir+sizeof(ir)/sizeof(int));

vector<int>::iterator itr = partition(x.begin(), x.end(), isOdd);

copy(x.begin(), itr, ostream_iterator<int>(cout, " "));
cout<<endl;
copy(itr, x.end(), ostream_iterator<int>(cout, " "));

输出:

7 9 
10 12 6 8

 

 

 

stack和vector都有 emplace函数,而stack其实是调用了底层容器的emplace_back,

都是C++11的。

The container is extended by inserting a new element at position. This new element is constructed in place using args as the arguments for its construction.

int main ()
{
  std::vector<int> myvector = {10,20,30};

  auto it = myvector.emplace ( myvector.begin()+1, 100 );
  myvector.emplace ( it, 200 );
  myvector.emplace ( myvector.end(), 300 );

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}


Output:
myvector contains: 10 200 100 20 30 300

 

posted @ 2017-03-03 15:22  blcblc  阅读(243)  评论(0编辑  收藏  举报