effective stl 部分算法或容器总结

stl 不熟悉的算法 algorithm

1.nth_element (a,a+n,a+m,cmp)

cmp 是一个比较函数

(这里 a+n,a+m 分别对应首迭代器 尾迭代器)

必须支持·随机访问迭代器的容器才能使用 当然数组也可以

用途 选择出 这个容器中第(n+1)小的元素

在他前的元素比他小 后面比他大 但是不一定有顺序 可以a[n]取出元素(字符串也可以)

2.next_permutation 和 previous_permutation

bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp);

comp 也可省

字典顺序

【用法总结】C++ STL中 next_permutation函数的用法_荷叶田田_的博客-CSDN博客

我之前总结过一次 但是可能是操作失误 没保存下来 就看别人的劳动成果吧

3.remove (迭代器a,迭代器b,待删除元素c)

STL函数——remove函数_SinHao22的博客-CSDN博客

这位博主讲的很好还讲了 remove与erase的区别

 erase 
iterator <T>::erase(iterator begin, iterator end);
void <T>::erase(iterator begin , iterator end);

有成员函数和非成员函数两个版本

大量删除元素时 采用区间erase

remove_if 可以针对判别式进行删除

remove_copy_if 拷贝到新容器 再与老容器互换

4.unique

iterator unique(iterator it_1,iterator it_2,bool MyFunc);

返回其尾迭代器

将相邻的相同元素“合并”,伪删除 与remove相似

STL函数——unique函数_stl unique_初学者清水的博客-CSDN博客

删除重复元素

4.rotate

非成员函数

template <class ForwardIterator>
ForwardIterator rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last);

(首迭代器,中迭代器,尾迭代器)

将中迭代器对应元素提升到首迭代器对应位置

如果超出区间则会显示 Segmentation fault

rotate_copy()
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy
 (ForwardIterator first, ForwardIterator middle,ForwardIterator last, OutputIterator result);
  rotate_copy(a.begin(),a.begin()+3,a.end(),ostream_iterator<int> (cout,“  ”));

使用一个输出迭代器 可以自己直接打印序列

5.reverse

0.algorithm 里的反转函数接口:reverse(first,last) 参数为容器的迭代器起始位置和终止位置

1.string和vector和deque只能使用模板库算法里的反转函数

2.list可以使用算法里的和list类的reverse

3.stack和queue没有迭代器,自然不能使用算法里的reverse,其类也没有提供反转的成员函数4.set和map的元素是按照键值排序的,不能修改键值,不可反转

http://t.csdn.cn/3uHsI

6.assign 赋值

void assign(const_iterator first,const_iterator last);

第一个相当于拷贝函数,把first到last的值赋值给调用者,注意区间的闭合,即:将区间 [first,last) 的元素赋值到当前的 vector 容器中

(不同容器间的拷贝也是可行的 但我没有尝试过所有的容器 并且不同的平台stl也存在差异 尽量同容器使用吧)

void assign(size_type n,const T& x = T());

第二个是把n个x赋值给调用者,即:赋 n 个值为 x 的元素到 vector 容器中,并且清除掉 vector 容器中以前的内容

这两个都是成员函数

7.copy

template <class inputIterator, class outputIterator>
outputIterator copy(inputIterator first1, inputIterator last, outputIterator first2);

(容器一的首迭代器,容器一的尾迭代器,容器2的首迭代器)

用于拷贝 和assign很相似 但它是非成员函数(目前我没去实验有太多不同的地方 有机会再补充)

注意: 所有的首/尾迭代器 都只是一个迭代器 为了方便表示区间 我这样记录 实际上不越界就行 (当然说不定越界也会产生很奇妙的反应 大概率会是内存泄露吧)

  1. insert

四种用法如上图 为成员函数

对vector容器一次插入大量元素 使用区间insert更加高效(不用多次调用insert函数 多次移动vector元素 多次扩展vector容器)

C++ STL vector插入元素(insert()和emplace())详解

里面也有emplace的用法

9.list的成员函数 splice

void splice (iterator position, list& x);
void splice (iterator position, list& x, iterator i);
void splice (iterator position, list& x, iterator first, iterator last);

position:指向目标列表中要插入元素的位置的迭代器。

x:指向源列表的迭代器。

i:指向源列表中要移动的元素的迭代器。

first 和 last:指定源列表中要移动的元素的范围。

这篇博客讲的很好!

10.

小技巧 使用swap来除去多余内存

这个 shrink-to-fit 我在源码中见过

在swap发生后 原先指向某容器中元素的迭代器,指针和引用依然有效 并指向同样的元素-但这些元素已经在另一个容器内了

  1. less_equal
template <class T> struct less_equal {
  bool operator() (const T& x, const T& y) const 
  {
     return x<=y;
  }
  1. equal_range 二分查找

必须有序

非成员函数

inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
 return __equal_range(first, last, value, distance_type(first),                    iterator_category(first));

(这个__equal_range()是源码当中的内容 详细的需要学习源码)

equal_range(首迭代器, 尾迭代器, 要查询的元素);

注意:这个返回的是pair容器

vector<int> a{1,2,3,3,3,3,4,5,7,8,9};
auto i=equal_range(a.begin(),a.end(),3);

i.first 是一个迭代器 如果没有这个元素则指向下一个元素的位置

i.second 指向下一个元素 也就是 相邻排序的元素

这个迭代器可以+-n 随机迭代器

也就是说这个序列中 i.first 指向第一个3

而i.sceond 指向4

这篇博客有介绍

http://t.csdn.cn/yR8KM

成员函数

该函数主要在unordered_map

C++中的unordered_map用法详解_zou_albert的博客-CSDN博客

上面是 unordered_map 介绍

(我在初始化的时候发现键可以重复 这点了解还很少 要记得研究)

http://t.csdn.cn/Tb295

unordered_map<int,string> b={{1,"qw"},{3,"we"},{3,"er"},{3,"rt"},{4,"ty"}};
 cout<<b.equal_range(1).first->first;

(感觉好复杂qwq)

13.lower_bound,upper_bound

有点类似equal_range

看这篇博客

http://t.csdn.cn/SAdrN

equal__range 使用了这两个函数

14.pair

#include <utility>
template <class T1,class T2> struct pair

pair将一对值(T1和T2)组合成一个值

这一对值可以具有不同的数据类型(T1和T2), 两个值可以分别用pair的两个公有函数first和second访问。

first ,second 都不用+();

可以直接初始化 也可以未初始化再使用make_pair(v1, v2);

来进行赋值

可以用tie来接受pair对象;

std::tie(name, ages) = getPreson();

getPerson()返回一个pair对象

  1. advance 非成员函数
template<class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n)
{
	typedef typename iterator_traits<InputIterator>::iterator_category category;
	__advance(i, n, category());    //重载时,编译期已经能确定调用哪个函数
}

相当于a+n 但更安全 效率取决于迭代器的类型;

16.distance 非成员函数

template<class InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
	typedef typename 
		iterator_traits<Iterator>::iterator_category category;
	return __distance(first, last, category());
}

返回两个迭代器之间的距离(可以是负数)

这里的两个迭代器可以是任意类型 但仍可能会导致某些错误

使用advance与distance 来安全的实现const_iterator 到iterator 的“转换” 实际上是一个新的迭代器 得到了旧迭代器的地址

17.base 成员函数

reverse_iterator.base()

可以让反向迭代器得到其对应位置的正向迭代器

但其得到的迭代器却不一定指向反向迭代器所指的位置

18.istream_Iterator 与 istreambuf_iterator

这就是两者的最大区别 我不太会总结

19.transform 成员函数

有两种重载

 template<class_InIt, class _OutIt, class _Fn1> inline
    _OutIt_Transform(_InIt _First, _InIt _Last,_OutIt _Dest, _Fn1 _Func)
    {  
 
        for(; _First != _Last; ++_First, ++_Dest)
            *_Dest= _Func(*_First);
        return(_Dest);
    }

从参数可看出InIt表示这个算法接收的迭代器类型为输入迭代器类型。参数需要需要容器开始迭代器_First,结束迭代器_OutIt,标识被拷贝容器元素区间,将这个区间中的元素拷贝到_Dest迭代器中所表示的容器中。这里要注意,目标容器中一定要有足够的空间。最后一个参数是一个函数对象或者普通函数,接收容器中的元素作为参数,我们可在此函数中对原容器中元素进行运算,将运算结果插入到目标容器中。

   template<class_InIt1,class _InIt2,class _OutIt,class _Fn2> inline
    _OutIt_Transform(_InIt1 _First1, _InIt1 _Last1,_InIt2 _First2, _OutIt _Dest, _Fn2_Func)
    {  
        for(; _First1 != _Last1; ++_First1, ++_First2, ++_Dest)
            *_Dest= _Func(*_First1, *_First2);
        return(_Dest);
    }

这个版本的transform算法可将两个容器中的元素经过Func运算存储到目标容器中。

都是看的人家博客 STL-transform算法_我的一亩三分地儿的博客-CSDN博客

另一篇博客 有一些细节上的补充 C++ transform(STL transform)函数用法详解

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值