C++ STL学习笔记-C++ STL基础

Posted ahappyfool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ STL学习笔记-C++ STL基础相关的知识,希望对你有一定的参考价值。

仅自己回忆使用,若有侵权,联系删除

algorithm实用库函数

sort:迭代器类型必须为随机访问迭代器(first,last),应该支持< 运算符,可以自己写比较

nth_element() > partial_sort() > sort() > stable_sort()       <--从左到右,性能由高到低

  1. 如果需要对所有元素进行排序,则选择 sort() 或者 stable_sort() 函数;
  2. 如果需要保持排序后各元素的相对位置不发生改变,就只能选择 stable_sort() 函数,而另外 3 个排序函数都无法保证这一点;
  3. 如果需要对最大(或最小)的 n 个元素进行排序,则优先选择 partial_sort() 函数;
  4. 如果只需要找到最大或最小的 n 个元素,但不要求对这 n 个元素进行排序,则优先选择 nth_element() 函数。
  5. 在实际选择排序函数时,应更多从所需要完成的功能这一角度去考虑,而不是一味地追求函数的性能。换句话说,如果你选择的算法更有利于实现所需要的功能,不仅会使整个代码的逻辑更加清晰,还会达到事半功倍的效果。
函数名 用法
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp) 对容器或普通数组中 [first, last) 范围内的元素进行排序,comare不写默认升序。返回bool类型bool mycomp(int i, int j)
void stable_sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp ); 和 sort() 函数功能相似,不同之处在于,对于 [first, last) 范围内值相同的元素,该函数不会改变它们的相对位置。
void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); 从 [first,last) 范围内,筛选出 muddle-first 个最小的元素并排序存放在 [first,middle) 区间中。
RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last,RandomAccessIterator result_first,RandomAccessIterator result_last, Compare comp); 从 [first, last) 范围内筛选出 result_last-result_first 个元素排序并存储到 [result_first, result_last) 指定的范围中。值得一提的是,[first, last] 中的这 2 个迭代器类型仅限定为输入迭代器,这意味着相比 partial_sort() 函数,partial_sort_copy() 函数放宽了对存储原有数据的容器类型的限制。换句话说,partial_sort_copy() 函数还支持对 list 容器或者 forward_list 容器中存储的元素进行“部分排序”,而 partial_sort() 函数不行。
bool is_sorted (ForwardIterator first, ForwardIterator last, Compare comp); 检测 [first, last) 范围内是否已经排好序,默认检测是否按升序排序。
ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last, Compare comp); 和 is_sorted() 函数功能类似,唯一的区别在于,如果 [first, last) 范围的元素没有排好序,则该函数会返回一个指向首个不遵循排序规则的元素的迭代器。
void nth_element (RandomAccessIterator first,RandomAccessIterator nth,RandomAccessIterator last,Compare comp); 找到 [first, last) 范围内按照排序规则(默认按照升序排序)应该位于第 nth 个位置处的元素,并将其放置到此位置。同时使该位置左侧的所有元素都比其存放的元素小,该位置右侧的所有元素都比其存放的元素大。
对于list有自己专有的sort

remove:ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)

fill:在 #include <algorithm> 头⽂件中,使⽤⽅法: fill(begin,end,val); fill(e[0], e[0] + 500 * 500, inf);

min : const T& min (const T& a, const T& b, Compare comp);

	ForwardIterator min_element ( ForwardIterator first, ForwardIterator last )

swap:void swap (T& a, T& b);

replace:void replace (ForwardIterator first, ForwardIterator last,const T& old_value, const T& new_value);

count:difference_type count (InputIterator first, InputIterator last, const T& val);

reverse:reverse(begin(v), end(v))

next_permutation()

next_permutation() 和  // 头⽂件 #include <algorithm> ,使⽤⽅法如下:
string s = "12345";  
do   
cout << s << endl;  
while(next_permutation(s.begin(), s.end()));  
最后得到54321

find:

InputIterator find (InputIterator first, InputIterator last, const T& val);
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);函数会根据指定的查找规则,在指定区域内查找第一个符合该函数要求(使函数返回 true)的元素。
InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred);和 find_if() 函数一样,find_if_not() 函数也适用于所有的容器,包括所有序列式容器和关联式容器。
所谓自定义查找规则,实际上指的是有一个形参且返回值类型为 bool 的函数。值得一提的是,该函数可以是一个普通函数(又称为一元谓词函数),比如:

bool mycomp(int i) 
  return ((i%2)==1);

目录页
C++ find_first_of()函数完全攻略
C++ find_end()函数详解
C++ search()函数用法完全攻略
C++ search_n()函数用法(超级详细)
set和map有专有的find,STL 标准库提供有 count()、find()、lower_bound()、upper_bound() 以及 equal_range() 这些函数,而每个关联式容器(除哈希容器外)也提供有相同名称的成员方法

binary_search,lower_bound,upper_bound,

 //在 [first, last) 区域内查找不小于 val 的元素,也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,const T& val);
//在 [first, last) 区域内查找第一个不符合 comp 规则的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,const T& val, Compare comp);

//查找[first, last)区域中第一个大于 val 的元素。
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,const T& val);
//查找[first, last)区域中第一个不符合 comp 规则的元素
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,const T& val, Compare comp);

upper_bound() 函数的功能和 lower_bound() 函数不同,前者查找的是大于目标值的元素,而后者查找的不小于(大于或者等于)目标值的元素。
distance(upper_bound(),lower_bound())就是相等的个数

//equel_range() 函数的功能完全可以看做是 lower_bound() 和 upper_bound() 函数的合体。
//找到 [first, last) 范围内所有等于 val 的元素
pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);

//查找 [first, last) 区域内是否包含 val
bool binary_search (ForwardIterator first, ForwardIterator last,
                      const T& val);
//根据 comp 指定的规则,查找 [first, last) 区域内是否包含 val
bool binary_search (ForwardIterator first, ForwardIterator last,
                      const T& val, Compare comp);

string::npos 用法

string s = "abcdefg";int idx = s.find(\'.\');   //作为return value,表示没有匹配项if (idx == string::npos)    cout << "This string does not contain any period!" << endl;idx = s.find(\'c\');s.replace(idx + 1, string::npos, "x");  string::npos作为长度参数,表示直到字符串结束cout << s;
  • 输出结果:

    This string does not contain any period!abcx
    

merge:

OutputIterator merge (InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);
可以看到,first1、last1、first2 以及 last2 都为输入迭代器,[first1, last1) 和 [first2, last2) 各用来指定一个有序序列;result 为输出迭代器,用于为最终生成的新有序序列指定存储位置;comp 用于自定义排序规则。同时,该函数会返回一个输出迭代器,其指向的是新有序序列中最后一个元素之后的位置。

merge(first, first + 5, second, second + 6, myvector.begin());

void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);其中,first、middle 和 last 都为双向迭代器,[first, middle) 和 [middle, last) 各表示一个有序序列。和 merge() 函数一样,inplace_merge() 函数也要求 [first, middle) 和 [middle, last) 指定的这 2 个序列必须遵循相同的排序规则

inplace_merge(first, first + 5,first +11);

不同之处在于,merge() 函数会将最终合并的有序序列存储在其它数组或容器中,而 inplace_merge() 函数则将最终合并的有序序列存储在 [first, last) 区域中。
对于list有自己专有的merge

尽量不自己定义迭代器指针指向迭代器,以免发生意外,当然如果确定的话也可以。

vector

初始化:

  1. std::vector<double> values;通过reserve() 函数来增加容器的容量values.reserve(20);调用 reserve() 不会影响已存储的元素,也不会生成任何元素已经大于或等于 20 个元素,那么这条语句什么也不做
  2. std::vector<int> primes 2, 3, 5, 7, 11, 13, 17, 19;
  3. std::vector<double> values(20);std::vector<double> values(20, 1.0);第二个参数指定了所有元素的初始值,因此这 20 个元素的值都是 1.0。值得一提的是,圆括号 () 中的 2 个参数,既可以是常量,也可以用变量来表示,例如:int num=20;double value =1.0;std::vector<double> values(num, value);
  4. std::vector<char>value1(5, \'c\'); std::vector<char>value2(value1);
  5. 可以用一对指针或者迭代器来指定初始值的范围,例如:
    int array[]=1,2,3;
    std::vector<int>values(array, array+2);//values 将保存1,2
    std::vector<int>value11,2,3,4,5;
    std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保1,2,3
    
函数成员 函数功能
begin() 返回指向容器中第一个元素的迭代器。
end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的迭代器。
rend() 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() 返回实际元素个数。
max_size() 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
resize() 改变实际元素的个数。
capacity() 返回当前容量。
empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
reserve() 增加容器的容量。
shrink _to_fit() 将内存减少到等于当前元素实际所使用的大小。
operator[ ] 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
at() 使用经过边界检查的索引访问元素。
front() 返回第一个元素的引用。
back() 返回最后一个元素的引用。
data() 返回指向容器中第一个元素的指针。
assign() 用新元素替换原有内容。
push_back() 在序列的尾部添加一个元素。
pop_back() 移出序列尾部的元素。
insert() 在指定的位置插入一个或多个元素。
erase() 移出一个元素或一段元素。
clear() 移出所有的元素,容器大小变为 0。
swap() 交换两个容器的所有元素。
emplace() 在指定的位置直接生成一个元素。
emplace_back() 在序列尾部生成一个元素。
语法格式 用法说明
iterator insert(pos,elem) 在迭代器 pos 指定的位置之前插入一个新元素elem,并返回表示新插入元素位置的迭代器。
iterator insert(pos,n,elem) 在迭代器 pos 指定的位置之前插入 n 个元素 elem,并返回表示第一个新插入元素位置的迭代器。
iterator insert(pos,first,last) 在迭代器 pos 指定的位置之前,插入其他容器(不仅限于vector)中位于 [first,last) 区域的所有元素,并返回表示第一个新插入元素位置的迭代器。
iterator insert(pos,initlist) 在迭代器 pos 指定的位置之前,插入初始化列表(用大括号括起来的多个元素,中间有逗号隔开)中所有的元素,并返回表示第一个新插入元素位置的迭代器。
erase(pos) 删除 vector 容器中 pos 迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会发生改变。
erase(beg,end) 删除 vector 容器中位于迭代器 [beg,end)指定区域内的所有元素,并返回指向被删除区域下一个位置元素的迭代器。该容器的大小(size)会减小,但容量(capacity)不会发生改变。
remove() 删除容器中所有和指定元素值相等的元素,并返回指向最后一个元素下一个位置的迭代器。值得一提的是,调用该函数不会改变容器的大小和容量。
clear() 删除 vector 容器中所有的元素,使其变成空的 vector 容器。该函数会改变 vector 的大小(变为 0),但不是改变其容量。

使用revise方法避免不必要扩容
不要使用vector<bool>
deque没有data()和capacity()函数,但是它的前端插入比vector快

array:还支持比较功能和字符串比较差不多

初始化:std::array<double, 10> values 0.5,1.0,1.5,,2.0;类似普通数组初始化

成员函数 功能
begin() 返回指向容器中第一个元素的随机访问迭代器。
end() 返回指向容器最后一个元素之后一个位置的随机访问迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的随机访问迭代器。需要注意的是,在使用反向迭代器进行 ++ 或 – 运算时,++ 指的是迭代器向左移动一位,-- 指的是迭代器向右移动一位,即这两个运算符的功能也“互换”了。
rend() 返回指向第一个元素之前一个位置的随机访问迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() 返回容器中当前元素的数量,其值始终等于初始化 array 类的第二个模板参数 N。
max_size() 返回容器可容纳元素的最大数量,其值始终等于初始化 array 类的第二个模板参数 N。
empty() 判断容器是否为空,和通过 size()==0 的判断条件功能相同,但其效率可能更快。
at(n) 返回容器中 n 位置处元素的引用,该函数自动检查 n 是否在有效的范围内,如果不是则抛出 out_of_range 异常。和[]类似,只是中括号不检查
front() 返回容器中第一个元素的直接引用,该函数不适用于空的 array 容器。
back() 返回容器中最后一个元素的直接应用,该函数同样不适用于空的 array 容器。
data() 返回一个指向容器首个元素的指针。利用该指针,可获得容器中的各个元素从而实现复制容器中所有元素等类似功能。
fill(val) 将 val 这个值赋值给容器中的每个元素。
array1.swap(array2) 交换 array1 和 array2 容器中的所有元素,但前提是它们具有相同的长度和类型。

array、vector 和 deque 容器的函数成员

函数成员 函数功能 array<T,N> vector deque
begin() 返回指向容器中第一个元素的迭代器。
end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的迭代器。
rend() 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
assign() 用新元素替换原有内容。 -
operator=() 复制同类型容器的元素,或者用初始化列表替换现有内容。
size() 返回实际元素个数。
max_size() 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
capacity() 返回当前容量。 - -
empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
resize() 改变实际元素的个数。 -
shrink\\ _to_fit() 将内存减少到等于当前元素实际所使用的大小。 -
front() 返回第一个元素的引用。
back() 返回最后一个元素的引用。
operator 使用索引访问元素。
at() 使用经过边界检査的索引访问元素。
push_back() 在序列的尾部添加一个元素。 -
insert() 在指定的位置插入一个或多个元素。 -
emplace() 在指定的位置直接生成一个元素。 -
emplace_back() 在序列尾部生成一个元素。 -
pop_back() 移出序列尾部的元素。 -
erase() 移出一个元素或一段元素。 -
clear() 移出所有的元素,容器大小变为 0。 -
swap() 交换两个容器的所有元素。
data() 返回指向容器中第一个元素的指针。 -

deque:

函数成员 函数功能
begin() 返回指向容器中第一个元素的迭代器。
end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的迭代器。
rend() 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() 返回实际元素个数。
max_size() 返回容器所能容纳元素个数的最大值。这通常是一个很大的值,一般是 232-1,我们很少会用到这个函数。
resize() 改变实际元素的个数。
empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
shrink _to_fit() 将内存减少到等于当前元素实际所使用的大小。
at() 使用经过边界检查的索引访问元素。
front() 返回第一个元素的引用。
back() 返回最后一个元素的引用。
assign() 用新元素替换原有内容。
push_back() 在序列的尾部添加一个元素。
push_front() 在序列的头部添加一个元素。
pop_back() 移除容器尾部的元素。
pop_front() 移除容器头部的元素。
insert() 在指定的位置插入一个或多个元素。
erase() 移除一个元素或一段元素。
clear() 移出所有的元素,容器大小变为 0。
swap() 交换两个容器的所有元素。
emplace() 在指定的位置直接生成一个元素。
emplace_front() 在容器头部生成一个元素。和 push_front() 的区别是,该函数直接在容器头部构造元素,省去了复制移动元素的过程。
emplace_back() 在容器尾部生成一个元素。和 push_back() 的区别是,该函数直接在容器尾部构造元素,省去了复制移动元素的过程。
和 vector 相比,额外增加了实现在容器头部添加和删除元素的成员函数,同时删除了 capacity()、reserve() 和 data() 成员函数。

stack

成员函数 功能
empty() 当 stack 栈中没有元素时,该成员函数返回 true;反之,返回 false。
size() 返回 stack 栈中存储元素的个数。
top() 返回一个栈顶元素的引用,类型为 T&。如果栈为空,程序会报错。
push(const T& val) 先复制 val,再将 val 副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。
push(T&& obj) 以移动元素的方式将其压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。
pop() 弹出栈顶元素。
emplace(arg…) arg… 可以是一个参数,也可以是多个参数,但它们都只用于构造一个对象,并在栈顶直接生成该对象,作为新的栈顶元素。
swap(stack & other_stack) 将两个 stack 适配器中的元素进行互换,需要注意的是,进行互换的 2 个 stack 适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。

quene:

成员函数 功能
empty() 如果 queue 中没有元素的话,返回 true。
size() 返回 queue 中元素的个数。
front() 返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
back() 返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
push(const T& obj) 在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。
emplace() 在 queue 的尾部直接添加一个元素。
push(T&& obj) 以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。
pop() 删除 queue 中的第一个元素。
swap(queue &other_queue) 将两个 queue 容器适配器中的元素进行互换,需要注意的是,进行互换的 2 个 queue 容器适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。

priority_queue<int,vector,cmp> cmp和sort的差不多

成员函数 功能
empty() 如果 queue 中没有元素的话,返回 true。
size() 返回 queue 中元素的个数。
front() 返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
back() 返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
push(const T& obj) 在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。
emplace() 在 queue 的尾部直接添加一个元素。
push(T&& obj) 以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。
pop() 删除 queue 中的第一个元素。
swap(queue &other_queue) 将两个 queue 容器适配器中的元素进行互换,需要注意的是,进行互换的 2 个 queue 容器适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。
和 stack 一样,queue 也没有迭代器,因此访问元素的唯一方式是遍历容器,通过不断移除访问过的元素,去访问下一个元素。

map

pair

	#include <iostream>
	#include <utility>      // pair
	#include <string>       // string
	using namespace std;
	int main() 
	    // 调用构造函数 1,也就是默认构造函数
	    pair <string, double> pair1;
	    // 调用第 2 种构造函数
	    pair <string, string> pair2("STL教程","http://c.biancheng.net/stl/");  
	    // 调用拷贝构造函数
	    pair <string, string> pair3(pair2);
	    //调用移动构造函数
	    pair <string, string> pair4(make_pair("C++教程", "http://c.biancheng.net/cplus/"));
	    // 调用第 5 种构造函数
	    pair <string, string> pair5(string("Python教程"), string("http://c.biancheng.net/python/"));  
	   
	    cout << "pair1: " << pair1.first << " " << pair1.second << endl;
	    cout << "pair2: "<< pair2.first << " " << pair2.second << endl;
	    cout << "pair3: " << pair3.first << " " << pair3.second << endl;
	    cout << "pair4: " << pair4.first << " " << pair4.second << endl;
	    cout << "pair5: " << pair5.first << " " << pair5.second << endl;
	    return 0;

//pair类模板还提供有一个 swap() 成员函数,能够互换 2 个 pair 对象的键值对,其操作成功的前提是这 2 个 pair 对象的键和值的类型要相同。

unordered_map和unordered_set
C++ STL关联式容器(map,set)

以上是关于C++ STL学习笔记-C++ STL基础的主要内容,如果未能解决你的问题,请参考以下文章

STL标准库 & 范型编程学习笔记:C++学习网站STL六大部件介绍

C++标准库 STL -- STL 体系结构基础介绍

C++ STL 相关 部分笔记

C++17 和 STL 学习笔记

C++笔记--面向对象(OOP)编程基础--STL入门与使用

STL标准库 & 范型编程学习笔记(10):hashtable深度探索