c++中容器之总结篇
C++中的容器大致可以分为两个大类:顺序容器和关联容器。顺序容器中有包含有顺序容器适配器。 一、顺序容器 1、顺序容器定义 定义示例 vector<int> vi; list<int> li; deque<int> di; 2、顺序容器初始化 初始化示例: //初始化为一个容器的副本 vector<int> vi; vector<int> vi2(vi); //利用vi来初始化vi2 //初始化为一段元素的副本 char*words[] = {"stately","plump","buck","mulligan"}; size_twords_size = sizeof(words)/sizeof(char*); list<string> words2(words,words + words_size); //分配和初始化指定数目的元素 constlist<int>::size_type list_size = 64; list<string> slist(list_size,"a"); // 64 strings,each is a 3、顺序容器支持的指针运算 ①所有顺序都支持的指针运行 ②vector 和 deque 容器的迭代器提供额外的运算 ③迭代器失效:一些容器操作会修改容器的内在状态或移动容器内的元素。这样的操作使所有指向被移动的元素的迭代器失效,也可能同时使其他迭代器失效。使用无效迭代器是没有定义的,可能会导致与悬垂指针相同的问题。 ④begin和end成员:begin和end操作产生指向容器内第一个元素和最后一个元素的下一位置的迭代器。 3、顺序容器操作 ①添加元素 添加元素示例: //在容器首部或者尾部添加数据 list<int> ilist; ilist.push_back(ix);//尾部添加 ilist.push_front(ix);//首部添加 //在容器中指定位置添加元素 list<string> lst; list<string>::iterator iter = lst.begin(); while (cin >> word) iter = lst.insert(iter,word); // 和push_front意义一样 //插入一段元素 list<string> slist; string sarray[4] = {"quasi","simba","frollo","scar"}; slist.insert(slist.end(),10,"A");//尾部前添加十个元素都是A list<string>::iterator slist_iter = slist.begin(); slist.insert(slist_iter,sarray+2,sarray+4);//指针范围添加 ②容器大小的操作 示例: list<int> ilist(10,1); ilist.resize(15); // 尾部添加五个元素,值都为0 ilist.resize(25,-1); // 再在尾部添加十个元素,元素为-1 ilist.resize(5); // 从尾部删除20个元素 ③访问元素 int vector<int> vi; for(int i=0;i<10;i++)vi.push_back(i); cout<<vi[0]<<endl; cout<<vi.at(0)<<endl; cout<<vi[10]<<endl; //越界错误 cout<<vi.at(10)<<endl;//越界错误 ④删除元素 示例: //删除第一个或最后一个元素 list<int> li; for(int i=0;i<10;i++)list.push_back(i); li.pop_front();//删除第一个元素 li.pop_back(); //删除最后一个元素 //删除容器内的一个元素 list<int>::iterator iter =li.begin(); if(iter!= li.end())li.erase(iter); //删除容器内所有元素 li.clear(); ⑤赋值与swap list<string> sl1,sl2; for(int i=0;i<10;i++)sl2.push_back("a"); sl1.assign(sl2.begin(),sl2.end());//用sl2的指针范围赋值,sl1中十个元素都为a sl1.assign(10,"A"); //s1被重新赋值,拥有十个元素,都为A swap示例: vector<string> vs1(3); // vs1有3个元素 ⑥vector的自增长:capacity 和 reserve 成员 为了提高vector的效率,不用每次添加元素都重新分配空间。vector会在分配空间时候预分配大于需要的空间。vector 类提供了两个成员函数:capacity 和reserve 使程序员可与 vector 容器内存分配的实现部分交互工作。 capacity(容量)与size(长度)的区别:size指容器当前拥有的元素个数,而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。capacity是比size大的一般情况下。 vector<int> ivec; cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;//都为0 for (vector<int>::size_type ix = 0; ix != 24; ++ix)ivec.push_back(ix); cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;//capacity大于size 可以通过函数reserve()来操作预留空间 //在之前一段代码的基础上 另外:如果不手动操作来预留空间,每当 vector 容器不得不分配新的存储空间时,以加倍当前容量的分配策略实现重新分配。 4、容器的选用 5、容器适配器 ①适配器通用的操作和类型 ②适配器的初始化 默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现。 vector<int> vi; deque<int> deq; stack<int> stk(deq); //用deq初始化stk stack<int> stk1(vi); //报错 ③适配器的操作 队列和优先级队列: 二、关联容器 1、pair ①pairs类型提供的操作 ②pairs类型定义和初始化 pair<string,string> test("A","B"); ③pairs其他操作 //pairs对象的操作 string firstBook; if (author.first == "James" && author.second == "Joyce")firstBook = "Stephen Hero"; //生成新的pair对象 pair<string,string> next_auth; next_auth = make_pair("A","B");//第一种方法 next_auth = pair<string,string>("A","B"); //第二种方法 cin>>next_auth.first>>next_auth.second;//第三种方法 2、map map 是键-值对的集合。map 类型通常可理解为关联数组:可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。 ①map对象的定义 map<string,int> word_count; 这个语句定义了一个名为 word_count 的 map 对象,由 string 类型的键索引,关联的值则int型。 ②map的构造函数 ③键类型的约束 ④map类定义的类型 value_type是存储元素的键以及值的pair类型,而且键为const。例如,word_count 数组的value_type 为pair<const string,int> 类型。value_type 是 pair 类型,它的值成员可以修改,但键成员不能修改。 ⑤map添加元素 示例: word_count.insert(map<string,int>::value_type("Anna",1)); word_count.insert(make_pair("Anna",1)); insert的返回值:包含一个迭代器和一个bool值的pair对象,其中迭代器指向map中具有相应键的元素,而bool值则表示是否插入了该元素。如果该键已在容器中,则其关联的值保持不变,返回的bool值为true。在这两种情况下,迭代器都将指向具有给定键的元素。 pair<map<string,int>::iterator,bool> ret = ret存储insert函数返回的pair对象。该pair的first成员是一个map迭代器,指向插入的键。ret.first从insert返回的pair对象中获取 map 迭代器;ret.second从insert返回是否插入了该元素。 ⑥查找并读取map中的元素 int occurs = 0; if (word_count.count("foobar"))occurs = word_count["foobar"]; map<string,int>::iterator it = word_count.find("foobar"); if (it != word_count.end())occurs = it->second; ⑦从map对象中删除元素 string removal_word = "a"; if (word_count.erase(removal_word)) cout << "ok: " << removal_word << " removedn"; else cout << "oops: " << removal_word << " not found!n"; 3、set ①set容器的定义和使用 vector<int> ivec; for (vector<int>::size_type i = 0; i != 10; ++i) { ivec.push_back(i); ivec.push_back(i); } set<int> iset(ivec.begin(),ivec.end()); cout << ivec.size() << endl; //20个 cout << iset.size() << endl; // 10个 ②在set中添加元素 set<string> set1; set1.insert("the"); //第一种方法:直接添加 set<int> iset2; iset2.insert(ivec.begin(),ivec.end());//第二中方法:通过指针迭代器 ③从set中获取元素 set<int> iset; for(int i = 0; i<10; i++)iset.insert(i); iset.find(1) // 返回指向元素内容为1的指针 iset.find(11) // 返回指针iset.end() iset.count(1) // 存在,返回1 iset.count(11) // 不存在,返回0 3、multimap 和 multiset ①迭代器的关联容器操作 以上就是本文的全部内容,希望对大家的学习有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |