1、std::string
字符串类,一块连续内存用于存放字符串,自动在结尾添加‘\0’结束符
int main()
{
std::string str("123");//"123"
int size = str.size();//size=3,与str.length()一样
str.push_back('4');//"1234"
str += "56";//"123456"
str.append("78");//"12345678"
str.insert(0,"9A");//"9A12345678"
str.replace(0,2,"BC");//"BC12345678"
std::string substr = str.substr(0,2);//substr="BC"
int i = str.find("56");//i=6
str.erase(0,2);//"12345678"
int capacity = str.capacity();//capacity=15,预留内存大小,值不固定,比size大
str.resize(10,'0');//"1234567800",原有字符不会被‘0’覆盖,如果重置大小小于str预留内存大小,则继续使用原来内存地址
capacity = str.capacity();//capacity=15
str.resize(16, '0');//重置大小大于str预留内存大小,重新分配内存
capacity = str.capacity();//capacity=31
str.assign("hello");//"hello"
str[0] = 'H';
std::cout << str << std::endl;//Hello
std::cout << str.c_str() << std::endl;//Hello
std::cout << str.data() << std::endl;//Hello
system("pause");
return 0;
}
2、std::vector
向量类,和数组差不多,用一块连续的内存保存数据,可以通过[]访问元素,访问效率较高,但是删除和添加中间元素效率不如list,因为删除和添加数据时需要重新移动数据保持内存连续。
int main()
{
std::vector<int> vect(2,0);//[0,0]
int size = vect.size();//size=2
vect.push_back(1);//[0,0,1]
vect.insert(vect.end(),2);//[0,0,1,2]
vect.resize(5,0);//[0,0,1,2,0]
vect.erase(vect.begin(), vect.begin()+2);//[1,2,0],不含vect.begin()+2
int arr[] = { 1,2,3,4,5};
vect.assign(&arr[0],&arr[4]);//[1,2,3,4],不含arr[4]
vect[0] = 0;//[0,2,3,4]
system("pause");
return 0;
}
vector数据大小超过预留内存时会重新分配内存,在数据量较大时,频繁分配内存会影响程序性能,如果能预先知道数据量大小,可通过vector::resize一次性分配内存,提升性能,如下测试程序:
int main()
{
int num = 100 * 10000;
_timeb t;
_ftime(&t);
std::cout << t.time << ":" << t.millitm << std::endl;
std::vector<int> vect1;
vect1.resize(num);
for (int i = 0; i < num; i++)
{
vect1[i] = i;
}
_ftime(&t);
std::cout << t.time << ":" << t.millitm << std::endl;
std::vector<int> vect2;
for (int i = 0; i < num; i++)
{
vect2.push_back(i);
}
_ftime(&t);
std::cout << t.time << ":" << t.millitm << std::endl;
system("pause");
return 0;
}
运行结果如下,可以看出使用resize快得多,std::string与vector一样也可以在数据量大时使用resize提升程序性能。另外push_back可由emplace_back替换,push_back首先构造临时对象,然后复制给vector元素以及删除临时对象,emplace_back直接调用元素构造函数构造vector元素,不需要临时对象的构造和复制及删除,可提高效率,其他类似容器也一样。
3、std::list
链表类,数据保存在不连续的内存中,使用指针串联所有数据,删除和添加数据效率较高,因为不需要移动内存,只要改变指向指针即可。
int main()
{
std::list<int> li(2, 0);//[0->0]
int size = li.size();//size=2
li.push_back(1);//[0->0->1]
li.push_front(2);//[2->0->0->1]
li.insert(li.end(), 3);//[2->0->0->1->3]
li.resize(6, 0);//[2->0->0->1->3->0]
li.remove(1);//[2->0->0->3->0]
li.erase(li.begin());//[0->0->3->0]
std::list<int>::iterator iter = li.begin();
iter++;
iter++;
li.erase(li.begin(),iter);//[3->0],不含iter
int arr[] = { 1,2,3,4,5 };
li.assign(&arr[0], &arr[4]);//[1->2->3->4],不含arr[4]
iter = li.begin();
*(++iter) = 0;//[1->0->3->4]
return 0;
}
4、std::deque
双端队列类,数据在内存中分块保存,在同一块内内存连续,在队列两端操作方便高效,同时也可以使用[]操作符访问元素,但效率没有vector高。
int main()
{
std::deque<int> dq(2,0);//[0,0]
int size = dq.size();//size=2
dq.push_back(1);//[0,0,1]
dq.push_front(2);//<=>[2,0,0,1]<=>
dq.insert(dq.begin(),3);//[3,2,0,0,1]
int front = dq.front();//front=3
int back = dq.back();//back=1
dq.front() = 0;//[0,2,0,0,1]
dq[1] = 4; //[0,4,0,0,1]
dq.pop_front();//[4,0,0,1]
dq.pop_back();//[4,0,0]
dq.erase(dq.begin()+1,dq.begin()+3);//[4]
return 0;
}
5、std::stack
栈,和std::queue称为容器适配器,使用其他容器实现,通过适配容器现有的接口来提供不同的功能。stack的特点是先进后出,后端进后端出,只能从一端进行操作,即栈顶(top)。
int main()
{
std::stack<int> st;//[]
int size = st.size();//size=0
st.push(1);//[1]
st.emplace(2);//[1,2]<-
int top = st.top();//top=2
st.top() = 0;//[1,0]
st.pop();//[1]
return 0;
}
6、std::queue
队列,特点是先进先出,类似排队,只能从后端进,前端出。
int main()
{
std::queue<int> q;//[]
int size = q.size();//size=0
q.push(1);//[1]
q.emplace(2);//<-[1,2]<-
int front = q.front();//front=1
int back = q.back();//back=2
q.pop();//[2]
q.front() = 0;//[0]
return 0;
}
7、std::map
map容器是关联容器,由键值对组成,键值唯一,添加的元素会以键值自动排序。
int main()
{
std::map<int, std::string> m{ {0,"zero"},{5,"five"} };//[(0,"zero"),(5,"five")]
int size = m.size();//size=2
m[3] = "three"; //[(0,"zero"),(3,"three"),(5,"five")]
m.emplace(2,"two"); //[(0,"zero"),(2,"two"),(3,"three"),(5,"five")]
m.insert(std::make_pair(1,"one")); //[(0,"zero"),(1,"one"),(2,"two"),(3,"three"),(5,"five")]
m[5] = "FIVE"; //[(0,"zero"),(1,"one"),(2,"two"),(3,"three"),(5,"FIVE")]
std::string str = m[1];//str="one"
std::map<int, std::string>::iterator iter = m.begin();
for (; iter != m.end(); iter++)//删除key为0的元素
{
if (iter->first == 0)
{
m.erase(iter);
break;//iter已经无效,不能继续循环,必须break
}
}
//如果要连续删除多个元素可以使用如下方法
for (iter = m.begin(); iter != m.end();)
{
auto tmpIter = iter;
if (iter->first == 2 || iter->first==3)//删除key为2和3的元素
{
tmpIter++;//删除iter之前指向下一个元素
m.erase(iter);
iter = tmpIter;
}
else
{
iter++;
}
}
m.erase(1); //[(5,"FIVE")]
return 0;
}
以上类需要分别包含头文件<string>,<vector>,<list>,<deque>,<stack>,<queue>和<map>