C++ Note 2
本文是我的C++笔记的第二篇 My Second C++ Note;
vector.clear()
vector.clear()
并不释放数组,其会调用data[0]...data[size-1]
的析构函数。 vector
在析构的时候会先调用clear()
然后释放数组 例如 1
2
3
4
5
6vector<int> x{1, 2, 4};
cout << x.capacity() << x.size() << endl; // 3 3
x.push_back(10);
cout << x.capacity() << x.size() << endl; // 6 4
x.clear();
cout << x.capacity() << x.size() << endl; // 6 0
1 |
|
这个会输出 1
2
3
4
5
6
7
8
9World()!
World()!
World()!
AAA
~World()!
~World()!
~World()!
BBB
clear and minimize
Before C++11
1 | vector<int> v{1,2,3,4,5}; |
After C++11
1 | vector<int> v{1,2,3,4,5}; |
partition()
按照规则进行进行分组 返回分出的第二组的首位的迭代器
例如 1
2
3
4vector<int> v{1, 2, 3, 4, 5, 6, 7};
partition(v.begin(), v.end(), [](int x)
{ return x % 2 == 0; });
pr(v);
得到 6 2 4 3 5 1 7 前面一组都是符合的 后面一组都是不符合的 可能会打乱顺序
对于不想打乱顺序的,使用stable_partition()
partial_sort()
1 | void partial_sort (RandomAccessIterator first, |
partial_sort() 会将 [first, last) 范围内最小(或最大)的 middle-first 个元素移动到 [first, middle) 区域中,并对这部分元素做升序(或降序)排序。
partial_sort() 函数: 容器支持的迭代器类型必须为随机访问迭代器。这意味着,partial_sort() 函数只适用于 array、vector、deque 这 3 个容器。 当选用默认的升序排序规则时,容器中存储的元素类型必须支持 <小于运算符;同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符; partial_sort() 函数在实现过程中,需要交换某些元素的存储位置。因此,如果容器中存储的是自定义的类对象,则该类的内部必须提供移动构造函数和移动赋值运算符。
partial_sort_copy()
partial_sort_copy() 函数的功能和 partial_sort() 类似,唯一的区别在于,前者不会对原有数据做任何变动,而是先将选定的部分元素拷贝到另外指定的数组或容器中,然后再对这部分元素进行排序。 1
2
3
4
5RandomAccessIterator partial_sort_copy (
InputIterator first,
InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last);
值得一提的是,[first, last] 中的这 2 个迭代器类型仅限定为输入迭代器,这意味着相比 partial_sort() 函数,partial_sort_copy() 函数放宽了对存储原有数据的容器类型的限制。换句话说,partial_sort_copy() 函数还支持对 list 容器或者 forward_list 容器中存储的元素进行“部分排序”,而 partial_sort() 函数不行。
但是,介于 result_first 和 result_last 仍为随机访问迭代器,因此 [result_first, result_last) 指定的区域仍仅限于普通数组和部分类型的容器,这和 partial_sort() 函数对容器的要求是一样的。
nth_element()
nth_element is a partial sorting algorithm that rearranges elements in [first, last) such that:
- The element pointed at by nth is changed to whatever element would occur in that position if [first, last) were sorted.
- All of the elements before this new nth element are less than or equal to the elements after the new nth element.
简单的理解 nth_element() 函数的功能,当采用默认的升序排序规则(std::less
is_sorted()
1 | //判断 [first, last) 区域内的数据是否符合 std::less<T> 排序规则,即是否为升序序列 |
is_sorted_until()
和 is_sorted() 函数相比,is_sorted_until() 函数不仅能检测出某个序列是否有序,还会返回一个正向迭代器,该迭代器指向的是当前序列中第一个破坏有序状态的元素。
1 | ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last); |
merge()
merge() 函数用于将 2 个有序序列合并为 1 个有序序列,前提是这 2 个有序序列的排序规则相同(要么都是升序,要么都是降序)。并且最终借助该函数获得的新有序序列,其排序规则也和这 2 个有序序列相同。 1
2
3OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);1
2
3//默认采用升序的排序规则
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last);
find() find_if()
1 | InputIterator find (InputIterator first, InputIterator last, const T& val); |
find() 函数本质上是一个模板函数,用于在指定范围内查找和目标元素值相等的第一个元素。 另外,该函数会返回一个输入迭代器,当 find() 函数查找成功时,其指向的是在 [first, last) 区域内查找到的第一个目标元素;如果查找失败,则该迭代器的指向和 last 相同。 值得一提的是,find() 函数的底层实现,其实就是用==
运算符将 val 和 [first, last) 区域内的元素逐个进行比对。这也就意味着,[first, last) 区域内的元素必须支持==
运算符。
和 find() 函数相同,find_if() 函数也用于在指定区域内执行查找操作。不同的是,前者需要明确指定要查找的元素的值,而后者则允许自定义查找规则。 1
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
find_end()与search()
序列A: 1,2,3,7,8,9,1,2,3,4 序列B: 1,2,3
find_end(A,B)返回B在A里面最后一次出现的位置 search(A,B)返回B在A里面第一次出现的位置
all_of(), any_of(), none_of()
algorithm 头文件中定义了 3 种算法,用来检查在算法应用到序列中的元素上时,什么时候使谓词返回 true。这些算法的前两个参数是定义谓词应用范围的输入迭代器;第三个参数指定了谓词。检查元素是否能让谓词返回 true 似乎很简单,但它却是十分有用的。
count(),count_if()
返回序列中 count(): 等于val的个数 count_if(): 满足pred的个数
C++中的map,filter,reduce
分别等价于transform,copy_if,accumulate
用法: #### copy_if 1
2
3
4
5vector<int> v{1, 2, 3, 4, 5, 6, 7};
vector<int> vv;
copy_if(begin(v), end(v), inserter(vv,begin(vv)), [](auto &x)
{ return x % 2 == 0; });
pr(vv);inserter
来创建了插入迭代器,从而实现向v2里面插入元素的功能
类似的 1
2
3
4
5vector<int> v{1, 2, 3};
vector<int> cc{11, 22, 33, 44};
copy_if(v.begin(), v.end(), back_inserter(cc), [](auto &x)
{ return x % 2 == 0; });
pr(cc);// 11 22 33 44 2back_inserter
向后面追加元素 ### transform 对容器里面的每个元素都做一次操作 ### accumulate 迭代所有元素并做类似求和等操作 1
2
3vector<int> v{1, 2, 3};
cout << accumulate(v.begin(), v.end(), v[0], [](auto &x, auto &y)
{ return x * y; });//will print 6
注意:当我们把accumulate作用在monoid上面的时候,要把第三个参数,即初始值设置为幺元.这有时候比较烦人。 那么,当我们已经确定了所处理的容器不会是空的的时候,可以这么写 1
2
3vector<int> v{1, 2, 3, 4};
cout << accumulate(next(begin(v)), end(v), v[0], [](auto &x, auto &y)
{ return x + y; });v[0]
之后再累加剩余的元素即可。
unique
unique() 算法可以在序列中原地移除重复的元素,这就要求被处理的序列必须是正向迭代器所指定的。在移除重复元素后,它会返回一个正向迭代器作为新序列的结束迭代器。可以提供一个函数对象作为可选的第三个参数,这个参数会定义一个用来代替 == 比较元素的方法。
for_each()
1 | vector<int> v{1, 2, 3}; |