目录
1.Set
2.Stack
3.Queue
4.Map
5.Vector
6.String
7.面试的STL问题
8.C++面试
1.Set
https://www.cnblogs.com/omelet/p/6627667.html
https://blog.csdn.net/yas12345678/article/details/52601454
set的特性是:
所有元素都会根据元素的键值自动排序(low_first)、除重;
set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值;
set不允许两个元素有相同的键值。
set的各成员函数列表如下:
1. begin() | --返回指向第一个元素的迭代器 | 11. lower_bound() | --返回指向大于(或等于)某值的第一个元素的迭代器 | 2. clear() | --清除所有元素 | 12. key_comp() | --返回一个用于元素间值比较的函数 | 3. count() | --返回某个值元素的个数 | 13. max_size() | --返回集合能容纳的元素的最大限值 | 4. empty() | --如果集合为空,返回true | 14. rbegin() | --返回指向集合中最后一个元素的反向迭代器 返回的值和end()相同 | 5. end() | --返回指向最后一个元素的迭代器 | 15. rend() | --返回指向集合中第一个元素的反向迭代器 返回的值和rbegin()相同 | 6. equal_range() | --返回集合中与给定值相等的上下限的两个迭代器 equal_range() ,返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。具体这个有什么用途我还没遇到过~~~ | 16. size() | --集合中元素的数目 | 7. erase() | --删除集合中的元素 erase(iterator) ,删除定位器iterator指向的值 erase(first,second),删除定位器first和second之间的值 erase(key_value),删除键值key_value的值 | 17. swap() | --交换两个集合变量 | 8. find() | --返回一个指向被查找到元素的迭代器 | 18. upper_bound() | --返回最后一个大于某个值元素的迭代器 | 9. get_allocator() | --返回集合的分配器 | 19. value_comp() | --返回一个用于比较元素间的值的函数 | 10. insert() | --在集合中插入元素 insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。 inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void. | | |
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int main()
{
int i;
int arr[5] = {0,1,2,3,4};
set<int> iset(arr,arr+5);//定义set 常用set<int> iset;
iset.insert(5);//插入一个元素
cout<<"size:"<<iset.size()<<endl;
cout<<"3 count = "<<iset.count(3)<<endl;
iset.erase(1);//删除元素1
set<int>::iterator ite1 = iset.begin();
set<int>::iterator ite2 = iset.end();//用迭代器取首尾元素
for(;ite1!=ite2;ite1++)//迭代器遍历
{
cout<<*ite1;//!!!!!注意指针
}
cout<<endl;
//遍历写法
/*
//遍历set,用迭代器类型
for(set<int>::iterator i=iset.begin();i!=iset.end();i++)
cout<<*i<<endl; //注意指针运算符
*/
ite1 = iset.find(3);//迭代器查找元素3,未找到就返回end()
if(ite1!=iset.end())
cout<<"3 found"<<endl;
ite1 = iset.find(1);
if(ite1!=iset.end())
cout<<"1 not found"<<endl;
}
我主要用set来排序和去重
但是去重过程中会自动排序
如果不想让它自动排序,可以用unorder_set,或者其他方法,这里留个坑总结去重
https://blog.csdn.net/weixin_42364203/article/details/109059918?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&dist_request_id=1328740.27333.16169173827075031&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
https://fesian.blog.csdn.net/article/details/104466995?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-5.control&dist_request_id=1328740.27333.16169173827075031&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-5.control
https://blog.csdn.net/dxx707099957/article/details/81032268?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.control&dist_request_id=1328741.27106.16169175282908977&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.control
2.Stack
https://blog.csdn.net/zichen_ziqi/article/details/80807989
https://blog.csdn.net/weixin_39645003/article/details/110590575?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_v2~rank_aggregation-16-110590575.pc_agg_rank_aggregation&utm_term=c%2B%2B%E6%A0%88%E7%9A%84%E9%81%8D%E5%8E%86&spm=1000.2123.3001.4430
特性:FILO、只能对栈顶进行插入和删除
常用操作:弹栈pop、压栈push、求栈的大小、判断栈是否为空、获取栈顶元素的值
s.empty(); //如果栈为空则返回true, 否则返回false; s.size(); //返回栈中元素的个数 s.top(); //返回栈顶元素, 但不删除该元素 s.pop(); //弹出栈顶元素, 但不返回其值 s.push(); //将元素压入栈顶
(1)基于数组的栈
#include <stack>
#include <iostream>
using namespace std;
int main()
{
stack<int> mystack;
int sum = 0;
for (int i = 0; i <= 10; i++){
mystack.push(i);
}
cout << "size is " << mystack.size() << endl;
while (!mystack.empty()){
cout << " " << mystack.top();
mystack.pop();
}
cout << endl;
system("pause");
return 0;
}
//size is 11
// 10 9 8 7 6 5 4 3 2 1 0
(2)基于单链表的栈
#include <iostream>
using namespace std;
template<class T>class Stack
{
private:
struct Node
{
T data;
Node *next;
};
Node *head;
Node *p;
int length;
public:
Stack()
{
head = NULL;
length = 0;
}
void push(T n)//入栈
{
Node *q = new Node;
q->data = n;
if (head == NULL)
{
q->next = head;
head = q;
p = q;
}
else
{
q->next = p;
p = q;
}
length++;
}
T pop()//出栈并且将出栈的元素返回
{
if (length <= 0)
{
abort();
}
Node *q;
T data;
q = p;
data = p->data;
p = p->next;
delete(q);
length--;
return data;
}
int size()//返回元素个数
{
return length;
}
T top()//返回栈顶元素
{
return p->data;
}
bool isEmpty()//判断栈是不是空的
{
if (length == 0)
{
return true;
}
else
{
return false;
}
}
void clear()//清空栈中的所有元素
{
while (length > 0)
{
pop();
}
}
};
int main()
{
Stack<char> s;
s.push('a');
s.push('b');
s.push('c');
while (!s.isEmpty())
{
cout << s.pop() << endl;
}
system("pause");
return 0;
}
用来做括号匹配、撤回、配对消除问题
用俩栈实现队列的push和pop
https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking&tab=answerKey
https://www.cnblogs.com/QG-whz/p/5170418.html#_label0
3.Queue
https://blog.csdn.net/luai_l/article/details/106597979
https://blog.csdn.net/chao_xun/article/details/8037438?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
https://blog.csdn.net/weixin_45826022/article/details/103297257
https://blog.csdn.net/chao_xun/article/details/8037438?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
FIFO
queue<int> q;
q.push(i); //将i添加到队列末尾
q.pop(); //弹出队列第一个元素
q.top(); //返回或修改第一个元素
q.front(); //返回或修改第一个元素 这两个成员函数在不同的编译器有不同的支持
q.size(); //返回队列元素个数
q.empty(); //判断队列是否为空
q.back(); //返回队列最后一个元素
priority_queue(优先队列):优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。
常用于BFS搜索 可见图的基本算法(BFS和DFS)
4.Map
https://www.cnblogs.com/omelet/p/6617362.html
https://zhuanlan.zhihu.com/p/127860466
map是STL容器,内部实现是红黑树,插入较慢,但是查找很快
map的特性是:
所有元素都会根据元素的减值自动被排序。
map的所有元素都是pair,同时拥有实值(value)和键值(key)。
pair的第一个元素会被视为键值,第二个元素会被视为实值。
map不允许两个元素拥有相同的键值。
map构造函数
map<string , int >strMap;
map<int ,string >intMap;
map<sring, char>strMap;
map< char ,string>charMap;
map<char ,int>charMap;
map<int ,char >intMap;
map添加数据
map<int ,string> maplive; 1.pair<int,string> value(1,"a");maplive.insert(value); 等价于maplive.insert(pair<int,string>(1,"a"));
2. maplive.insert(map<int,string>::value_type(1,"a"));
3. maplive[1]="a";//map中最简单最常用的插入添加!
map容器内元素的访问
- 通过下标进行访问 如:maps['c']=5;
- 通过迭代器进行访问 map可以使用it->first来访问键,使用it->second访问值
map的基本操作函数
begin() 返回指向map头部的迭代器 | key_comp() 返回比较元素key的函数 | clear() 删除所有元素 | lower_bound() 返回键值>=给定元素的第一个位置 | count() 返回指定元素出现的次数 | max_size() 返回可以容纳的最大元素个数 | empty() 如果map为空则返回true | rbegin() 返回一个指向map尾部的逆向迭代器 | end() 返回指向map末尾的迭代器 | rend() 返回一个指向map头部的逆向迭代器 | equal_range() 返回特殊条目的迭代器对 | size() 返回map中元素的个数 | erase() 删除一个元素 | swap() 交换两个map | find() 查找一个元素 | upper_bound() 返回键值>给定元素的第一个位置 | get_allocator() 返回map的配置器 | value_comp() 返回比较元素value的函数 | insert() 插入元素 | |
map的常用用法
// 定义一个map对象
map<int, string> m;
//用insert函数插入pair
m.insert(pair<int, string>(111, "kk"));
// 用insert函数插入value_type数据
m.insert(map<int, string>::value_type(222, "pp"));
// 用数组方式插入
m[123] = "dd";
m[456] = "ff";
find(key): 返回键是key的映射的迭代器
map<string,int>::iterator it;
it=maps.find("123");
//迭代器刪除
it = maps.find("123");
maps.erase(it);
//关键字删除
int n = maps.erase("123"); //如果刪除了返回1,否则返回0
//用迭代器范围刪除 : 把整个map清空
maps.erase(maps.begin(), maps.end());
//等同于mapStudent.clear()
int len=maps.size();获取到map中映射的次数
- maps.begin()返回指向map头部的迭代器
- maps.end()返回指向map末尾的迭代器
//迭代
map< string,int>::iterator it;
for(it = maps.begin(); it != maps.end(); it++)
cout<<it->first<<" "<<itr->second<<endl;//输出key 和value值
- maps.rbegin()返回指向map尾部的逆向迭代器
- maps.rend()返回指向map头部的逆向迭代器
//反向迭代
map<string,int>::reverse_iterator it;
for(it = maps.rbegin(); it != maps.rend(); it++)
cout<<it->first<<' '<<it->second<<endl;
- maps.empty()判断其是否为空
- maps.swap()交换两个map
#include <iostream>
#include "string.h"
#include "stdio.h"
#include<map>
using namespace std;
int main(){
map<string,int> strMap; //以string为键值,以int为实值
strMap[string("jjhou")] = 1;
strMap[string("jerry")] = 2;
strMap[string("jason")] = 3;
strMap[string("jimmy")] = 4;
pair<string,int> value(string("david"),5);
strMap.insert(value);//插入新元素
map<string,int>::iterator strmap_iter = strMap.begin();
for(;strmap_iter !=strMap.end();strmap_iter++)
{
cout<<strmap_iter->first<<' '<<strmap_iter->second<<endl;
}
cout<<endl;
int number = strMap[string("jjhou")];
cout<<number<<endl;
cout<<endl;
//查找元素
map<string,int>::iterator iter1;
//面对关联式容器,应该使用其所提供的find函数来搜索元素,会比使用STL算法find()更有效率。因为STL算法find()只是循环搜索。
iter1 = strMap.find(string("mchen"));
if(iter1 == strMap.end())
cout<<"mchen no fount"<<endl;
cout<<endl;
iter1 = strMap.find(string("jerry"));
if(iter1 != strMap.end())
cout<<"jerry fount"<<endl;
cout<<endl;
//修改实值,键值不可修改
iter1->second = 9; //可以通过map迭代器修改“value”(not key)
int number1 = strMap[string("jerry")];
cout<<number1<<endl;
//删除元素
map<string,int>::iterator strmap_iter1 = strMap.begin();
for(;strmap_iter1 !=strMap.end();strmap_iter1++)
{
cout<<strmap_iter1->first<<' '<<strmap_iter1->second<<endl;
}
cout<<endl;
strMap.erase(iter1);//删除一个条目
strMap.erase(string("jason"));//根据键值删除
map<string,int>::iterator strmap_iter2 = strMap.begin();
for(;strmap_iter2 !=strMap.end();strmap_iter2++)
{
cout<<strmap_iter2->first<<' '<<strmap_iter2->second<<endl;
}
}
https://blog.csdn.net/zhoucheng_123/article/details/104226007
https://blog.csdn.net/weixin_50525909/article/details/113407592?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328741.27947.16169254098096427&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
https://blog.csdn.net/shuzfan/article/details/53115922?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control&dist_request_id=1328741.27936.16169254412847411&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control
5.Vector
https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html
https://www.zhihu.com/question/35050138
http://c.biancheng.net/view/416.html
https://www.jianshu.com/p/9797be723935
vector是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,vector是一个能够存放任意类型的动态数组。
1. vector 说明
1)vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
2.)vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
3.)进行vector操作前需添加头文件#include <vector>
4.)vector属于std命名域的,需要通过命名限定,完成代码。
2. vector 初始化
方式1.
vector<int>a(10);
定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定.
方式2.
vector<int>a(10,1);
定义具有10个整型元素的向量,且给出的每个元素初值为1.
方式3.
vector<int>a(b);
用向量b给向量a赋值,a的值完全等价于b的值
方式4.
vector<int>a(b.begin(),b.begin+3);
将向量b中从0-2(共三个)的元素赋值给a,a的类型为int型
方式5.
int b[7]={1,2,3,4,5,6,7};
vector<int> a(b,b+7);
从数组中获得初值,复制[b, b+7)区间内另一个数组的元素到vector中(0-7)
3.成员函数
c.assign(a.begin(), a.begin() + 3); //a为向量,将a的0-2(共三个)元素赋值给向量c
d.assign(4, 2); //d含有4个值为2的元素
c.back() // 传回最后一个数据,不检查这个数据是否存在。
c.begin() // 传回迭代器中的第一个数据地址。
c.capacity() // 返回容器中总共可以容纳的数据个数。
c.clear() // 移除容器中所有数据。
c.empty() // 判断容器是否为空,空则返回true,非空则返回false。
c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
c.erase(pos) // 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg, end) //删除[beg,end)区间的数据,传回下一个数据的位置。
c.front() //返回c的第一个元素
get_allocator // 使用构造函数返回一个拷贝。
c.insert(pos, elem) // 在pos位置插入一个elem拷贝,传回新数据位置。
c.insert(pos, n, elem) // 在pos位置插入n个elem数据。无返回值。
c.insert(pos, beg, end) // 在pos位置插入在[beg,end)区间的数据。无返回值。
c.max_size() // 返回容器中最大数据的数量。
c.pop_back() // 删除最后一个数据。
c.push_back(elem) // 在尾部加入一个数据。
c.rbegin() // 传回一个逆向队列的第一个数据。
c.rend() // 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) // 重新指定队列的长度。
c.reserve() // 保留适当的容量。
c.size() // 返回容器中实际数据的个数。
c1.swap(c2)
swap(c1, c2) // 将c1和c2元素互换。同上操作。
operator[] // 返回容器中指定位置的一个引用。
a[i]; //返回a的第i元素,当且仅当a存在
a.resize(10); //将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10, 2); //将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.reserve(100); //将a的容量扩充至100,
a == b; //b为向量,向量的比较操作还有 != >= > <= <
assign函数:
函数原型:
void assign(const_iterator first,const_iterator last);
void assign(size_type n,const T& x = T());
功能:
将区间[first,last)的元素赋值到当前的vector容器中,或者赋n个值为x的元素到vector容器中,这个容器会清除掉vector容器中以前的内容。
顺序访问vector
1.对向量a添加元素
1).向向量a中添加元素
vector<int>a; for(int i=0;i<10;++i){a.push_back(i);}
2).从数组中选择元素向向量中添加
int a[6]={1,2,3,4,5,6}; vector<int> b; for(int i=0;i<=4;++i){b.push_back(a[i]);}
3).从现有向量中选择元素向向量中添加
int a[6]={1,2,3,4,5,6}; vector<int>b; vector<int>c(a,a+4); for(vector<int>::iterator it=c.begin();it<c.end();++it) { b.push_back(*it); }//b中加c,c是a的1-4
4).从文件中读取元素向向量中添加
ifstream in("data.txt"); vector<int>a; for(int i;in>>i){a.push_back(i);}
2. 从向量中读取元素
int main()
{
int b[7] = { 1,2,3,4,5,6,7 };
vector<int> a(b, b + 7); //复制[b, b+7)区间内另一个数组的元素到vector中
for (size_t i=0; i < a.size(); ++i) {
cout <<"向量a的值为:"<< a[i] << endl;
}
vector<int>c;
//a为向量,将a的0-2(共三个)元素赋值给向量c
c.assign(a.begin(), a.begin() + 3);
for (auto it = c.begin(); it != c.end(); ++it)
{
cout << "向量c的值为:" << *it << endl;
}
vector<int>d;
//d含有4个值为2的元素
d.assign(4, 2);
for (auto it = d.begin(); it != d.end(); ++it)
{
cout << "向量d的值为:" << *it << endl;
}
return 0;
}
常用的算法
//对a中的[a.begin(),a.end())的元素进行从小到大排列
sort(a.begin(), a.end());
//对a中的从[a.begin(),a.end())的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
reverse(a.begin(), a.end());
//把a中的从[a.begin(),a.end())的元素复制到c中,从c.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
copy(a.begin(), a.end(), c.begin() + 1);
//在a中的从[a.begin(),a.end())的元素中查找10,若存在返回其在向量中的位置
find(a.begin(), a.end(), 10);
注意内存管理与效率
1.使用reserve()函数提前设定容量大小,避免多次容量扩充操作导致效率低下
例如,假定你想建立一个容纳1-1000值的vector<int>。没有使用reserve,你可以像这样来做:
vector<int> v;
for (int i = 1; i <= 1000; ++i)
v.push_back(i);
在大多数STL实现中,这段代码在循环过程中将会导致2~10次重新分配。 (10这个数没什么奇怪的。记住vector在重新分配发生时一般把容量翻倍,而1000约等于210。)
把代码改为使用reserve,我们得到这个:
vector<int> v;
v.reserve(1000);
for (int i = 1; i <= 1000; ++i)
v.push_back(i);
这在循环中不会发生重新分配。
在大小和容量之间的关系让我们可以预言什么时候插入将引起vector或string执行重新分配,而且,可以预言什么时候插入会使指向容器中的迭代器、指针和引用失效。例如,给出这段代码,
string s;
...
if (s.size() < s.capacity()) {
s.push_back('x');
}
push_back的调用不会使指向这个string中的迭代器、指针或引用失效,因为string的容量保证大于它的大小。如果不是执行push_back,代码在string的任意位置进行一个insert,我们仍然可以保证在插入期间没有发生重新分配,但是,与伴随string插入时迭代器失效的一般规则一致,所有从插入位置到string结尾的迭代器/指针/引用将失效。
回到本条款的主旨,通常有两情况使用reserve来避免不必要的重新分配。
- 第一个可用的情况是当你确切或者大约知道有多少元素将最后出现在容器中。那样的话,就像上面的vector代码,你只是提前reserve适当数量的空间。
- 第二种情况是保留你可能需要的最大的空间,然后,一旦你添加完全部数据,修整掉任何多余的容量。
2. 使用“交换技巧”来修整vector过剩空间/内存
有一种方法来把它从曾经最大的容量减少到它现在需要的容量。这样减少容量的方法常常被称为“收缩到合适(shrink to fit)”。该方法只需一条语句:
vector<int>(ivec).swap(ivec);
表达式vector<int>(ivec)建立一个临时vector,它是ivec的一份拷贝:vector的拷贝构造函数做了这个工作。但是,vector的拷贝构造函数只分配拷贝的元素需要的内存,所以这个临时vector没有多余的容量。然后我们让临时vector和ivec交换数据,这时我们完成了,ivec只有临时变量的修整过的容量,而这个临时变量则持有了曾经在ivec中的没用到的过剩容量。在这里(这个语句结尾),临时vector被销毁,因此释放了以前ivec使用的内存,收缩到合适。
3. 用swap方法强行释放STL Vector所占内存
template < class T> void ClearVector( vector<T>& v )
{
vector<T>vtTemp;
vtTemp.swap( v );
}
如
vector<int> v ;
nums.push_back(1);
nums.push_back(3);
nums.push_back(2);
nums.push_back(4);
vector<int>().swap(v);
/* 或者v.swap(vector<int>()); */
/*或者{ std::vector<int> tmp = v; v.swap(tmp); }; //加大括号{ }是让tmp退出{ }时自动析构*/
动态数组的作用吧,算法题都用它
https://blog.csdn.net/haohaoxuexilmy/article/details/81174169?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&dist_request_id=1328741.27947.16169254098096427&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control
6.String
https://zhuanlan.zhihu.com/p/136244569
http://c.biancheng.net/view/400.html
C#中的String时引用类型https://jingyan.baidu.com/article/19020a0a4828bd529d28420a.html
JAVA中的也是引用类型,有时表现出一定的值特性https://blog.csdn.net/a220315410/article/details/27743607
string s1(); // si = ""
string s2("Hello"); // s2 = "Hello"
string s3(4, 'K'); // s3 = "KKKK"
string s4("12345", 1, 3); //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串
/*
//string 类没有接收一个整型参数或一个字符型参数的构造函数。下面的两种写法是错误的:
string s1('K');
string s2(123);
*/
//对 string 对象赋值
int main()
{
string s,ss;
cin>>ss;
s="";//必须有
for(int i=0;i<ss.length();i++)
{
s+=ss[i];
}
cout<<ss<<endl;
}
/*
//错误
int main()
{
string s,ss;
cin>>ss;
for(int i=0;i<ss.length();i++)
s[i]=ss[i];
cout<<s<<endl;
}
*/

7.面试的STL问题
https://blog.csdn.net/weixin_41055260/article/details/109249974?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328741.27947.16169254098096427&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
vector的底层原理:
vector中的reserve和resize的区别
vector中的size和capacity的区别
vector中erase方法与algorithn中的remove方法区别
vector迭代器失效的情况
正确释放vector的内存(clear(), swap(), shrink_to_fit())
list的底层原理
什么情况下用vector,什么情况下用list,什么情况下用deque
priority_queue的底层原理
map 、set、multiset、multimap的底层原理
红黑树的特性:
为何map和set的插入删除效率比其他序列容器高
为何map和set每次Insert之后,以前保存的iterator不会失效?
当数据元素增多时(从10000到20000),map的set的查找速度会怎样变化?
map 、set、multiset、multimap的特点
为何map和set的插入删除效率比其他序列容器高,而且每次insert之后,以前保存的iterator不会失效?
为何map和set不能像vector一样有个reserve函数来预分配数据?
set的底层实现实现为什么不用哈希表而使用红黑树?
hash_map与map的区别?什么时候用hash_map,什么时候用map? 构造函数:hash_map需要hash function和等于函数,而map需要比较函数(大于或小于)。
迭代器失效的问题
线程不安全的情况
8.C++面试
https://blog.csdn.net/weixin_43778179/article/details/90236445?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=1328753.6854.16171492575013319&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control |