string
1. string和char*有什么区别呢?
string是类,而char*是一个指向字符串的指针;string是一个char *类型的容器,它封装了char *,以及字符串操作相关的函数,并且string可以自动管理内存,不用考虑内存回收和访问越界问题。
2. string类中at成员函数和[]操作符区别?
当访问越界时,at可以抛出异常,[]直接编译报错。
3. 常用成员函数整理
1. //构造函数 2. string(); 3. string(const string &str); 4. string(const char *s); 5. string(int n,char c); 6. 7. //字符访问 8. const char &operator[] (int n) const; 9. const char &at(int n) const; 10. char &operator[] (int n); 11. char &at(int n); 12. 13. //获取字符串const char * 14. const char *c_str() const; 15. 16. //字符拷贝 17. int copy(char *s, int n, int pos=0) const; 18. 19. //字符串长度 20. int length() const; 21. 22. //判断字符串是否为空 23. bool empty() const; 24. 25. //字符串赋值 26. string &operator=(const string &s); 27. string &assign(const char *s); //该函数有多个重载 28. 29. //字符串追加(连接) 30. string &operator+=(const string &s); 31. string &operator+=(const char *s); 32. string &append(const char *s); //该函数有多个重载 33. 34. //字符串比较 35. int compare(const string &s) const; 36. int compare(const char *s) const; 37. 38. //查找 39. int find(char c,int pos=0) const; //该函数有多个重载 40. 41. //替换 42. string &replace(int pos, int n, const char *s); //该函数有多个重载 43. 44. //插入 45. string &insert(int pos, const char *s); 46. 47. //删除 48. string &erase(int pos=0, int n=npos);
vector
1. vector为什么在尾部插入删除效率更高?
vector是一个动态单端数组,在尾部插入和删除效率更高,原因是在头部或者中间插入元素,那么插入位置后面的元素都要往后移一位,在头部或者中间删除一个元素,那么被删除元素后面的元素都会往前移动一位,这会产生大量的元素移动,所以效率和速度较低。在尾部插入或删除就不会产生这样的大量元素移动。
2. []和push_back的区别
[]操作时必须提前分配内存,而push_back不需提前分配内存,push_back是动态分配内存的;
[]可以随机存取,push_back只能在尾部插入元素;
1. vector<int> v(10); 2. v.push_back(1); 3. v.push_back(2); 4. //v.size() = 12 因为push_back是在尾部插入,会动态分配内存
3. 迭代器的指向
begin()指向第一个元素,而end()指向最后一个元素的后面位置。
容器元素 | 1 | 2 | 3 | |
迭代器 | 🔺 begin() |
|||
🔺 end() |
erase在删除元素后会自动使迭代器 it 后移,并返回移动后的迭代器位置.
1. //删除容器中的元素2 2. for(vector<int>::iterator it = v.begin(); it != v.end();) 3. { 4. if(*it == 2) 5. { 6. it = v.erase(it); //erase在删除元素后会自动使迭代器 it 后移,并返回移动后的迭代器位置 7. } 8. else 9. { 10. it++; 11. } 12. }
3. 常用成员函数
1. vector.size(); //容器大小 2. vector.empty(); //容器是否为空 3. vector.resize(len); //重新指定大小 4. vector.assign(beg,end); //将[beg, end)的值拷贝复制 5. vector.push_back(e); //在尾部放入元素 6. vector.at(index); //访问index处的元素 可抛出异常 7. vector[index]; //访问index处的元素 8. vector.front(); //返回头部元素 9. vector.back(); //返回尾部元素 10. vector.insert(pos,e); //在pos处插入e //该函数有多个重载 11. vector.clear(); //移除容器的所有数据 12. vec.erase(beg,end); //删除[beg, end)区间内数据 //该函数有多个重载
deque
双端数组,两端都可以插入删除。
1. deque.push_back(e); //在容器尾部放入一个数据 2. deque.push_front(e); //在容器头部放入一个数据 3. deque.pop_back(); //删除容器最后一个数据 4. deque.pop_front(); //删除容器第一个数据 5. deque.at(index); //访问index处数据,可抛出异常 6. deque[index]; //访问index处数据,不可抛出异常 7. deque.begin(); //返回容器中第一个元素的迭代器 8. deque.end(); //返回容器中最后一个元素的迭代器 9. deque.size(); 10. deque.empty(); 11. deque.resize(len); 12. deque.insert(pos, e); //含有多个重载 13. deque.clear(); 14. deque.erase(beg,end); 15. deque.erase(pos);
stack
栈,后进先出。
1. stack.push(e); //入栈 2. stack.pop(); //出栈 3. stack.top(); //返回栈顶元素 4. stack.size(); //栈大小 5. stack.empty(); //栈判空
queue
queue队列,先进先出,固定一端进一端出,队尾进,队头出。priority_queue 是优先级队列。
1. queue.push(e); //往队尾添加元素 2. queue.pop(); //弹出队头的元素 3. queue.back(); 4. queue.front(); 5. queue.empty(); 6. queue.size();
list
双向链表,不支持随机访问,所以迭代器 it 不能 it+2 这种操作,一次只能移动一步 it++。
1. list.push_back(e); //尾插 2. list.push_front(e); //头插 3. list.pop_back(); //删除链表中尾部元素 4. list.pop_front(); //删除链表中头部元素 5. list.front(); //返回链表一个元素 6. list.back(); //返回链表最后一个元素 7. list.begin(); //返回链表第一个元素的迭代器 8. list.end(); //返回链表尾部元素的迭代器 9. list.size(); 10. list.empty(); 11. list.resize(num); 12. list.insert(pos,e); //含有多个重载 13. list.clear(); //移除链表的所有数据 14. list.erase(beg,end); //删除[beg, end)区间内数据 //多个重载 15. list.reverse(); //反转链表
set
集合容器,元素唯一且按一定规则有序排列,关于set排序功能的实现和函数对象可以参考本人这篇博客
multi_set 同一值可以出现多次。
map
键值对容器<key, value>,键值key唯一,且按照一定规则排序,可以根据key随机访问对应value,也就是说对key支持[]操作。multi_map,相同键值可以重复。
1. insert插入和[]插入有什么区别?
1. map<int, string> m; 2. 3. m.insert(make_pair(1, "string1")); 4. m.insert(make_pair(1, "string2")); //插入失败 5. 6. m[3] = "string3"; 7. m[3] = "string4"; //覆盖原来的
2. 常用成员函数
1. //元素插入 2. map.insert(pair<int, string>(1, "111")); 3. map.insert(make_pair(1, "111")); 4. map.insert(map<int, string>::value_type(1, "111")); 5. map[1] = "111"; 6. 7. map.size(); 8. map.empty(); 9. map.clear(); 10. map.erase(pos); 11. map.find(key);
区别与相同点
1. 区别
vector | stack | queue | deque | list | set | multi_set | map | multi_map | |
数据结构 | 单端 数组 |
栈 | 队列 | 双端 数组 |
双向链表 | 二叉树 | 二叉树 | 二叉树 | 二叉树 |
随机访问 | 支持 | 不支持 | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 对key支持 | 不支持 |
2. 相同点
所有容器提供的都是值语意(value),而不是引用语意(reference)。也就是说向容器中插入元素时,实行的是拷贝行为。所以,向容器中装入元素时必须保证元素能够被拷贝(必须提供拷贝构造函数实现深拷贝)。