顺序容器操作
向顺序容器添加元素
forward_list //有自己专有版本的insert和emplace; forward_list //不支持push_back和emplace_back vector, string //不支持push_front和emplace_front c.push_back(t), c.emplace_back(args) //在c的尾部创建一个值为t的或者由args创建的元素,返回void c.push_front(t), c.emplace_back(args) //同上,吧尾部改为头部 c.insert(p,t), c.emplace(p,args) //在迭代器p的前面创建一个t或由args生产一个值插入,返回指向新添加元素的迭代器 c.insert(p, n, t) //在迭代器p指向的元素之前插入n个t值,返回指向新添加的第一个值的迭代器。 c.insert(p, b, e) //吧迭代器b,e之间的元素插入到p之前,返回指向新添加的第一个元素 c.insert(p, il) //il是一个花括号包围的元素值列表。同上
使用push_back
//从标准输入读取数据,将每个单词放到容器末尾 string word; while(cin>>word) container.push_back(word);
由于string是一个字符容器,我们可以用push_back在string末尾添加字符:
void pluralize(size_t cnt, string &word) { if(cnt > 1) word.push_back('s'); //等价word +='s' }
使用push_front
这个操作是吧元素插入到容器头部,
list<int> ilist; for(size_t ix=0 ; ix != 4 ; ++ix) { ilist.push_front(ix); }
向容器总的特定位置添加元素
insert提供更加一般的添加功能,随机插入。
有些容器不支持push_front,但它们对于insert操作并无类似的限制
vector<string> svec; list<string> slist; //等价于调用slist.push_front("Hello!"); slist.insert(slist.begin(), "Hello!"); svec.insert(svec.begin(), "Hello!"); //速度回比较慢
使用emplace操作
//在c的末尾构造一个Sales_data对象 //使用三个参数的Sales_data构造函数 c.emplace_back("978-0590353403", 25, 15.99); //错误:没有接受三个参数的push_back版本 c.push_back("978-0590353403", 25, 15.99); //正确:创建一个临时的Sales_data对象传递给push_back c.push_back(Sales_data("978-0590353403", 25, 15.99));
emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。
访问元素
//在解引用一个迭代器或调用front或front之前检查是否有元素 if(!c.empty()) { //val和val2是c中第一个元素值的拷贝 auto val=*c.begin(), val2=c.front(); //val3和val4是c中最后一个元素值的拷贝 auto last=c.end(); auto val3=*(--last); //不能递减forward_list迭代器 auto val4=c.back(); //forward_list不支持 }
这里还有两种访问方式
at和下标操作
但是只适用于string, vector, deque, array
c[n] //返回c中下标为n的元素引用 c.at(n) //返回c中下标为n的元素引用
访问成员函数返回的是引用,下标操作和安全的随机访问
vector下标是从0开始的,但是如果vector为空的话,那么
vector<string> svec; //空vector cout<<svec[0]; //运行错误,vector是空的 cout<<svec.at(0); //抛出一个out_of_range异常
删除元素
c.pop_back() //删除c中尾元素 c.pop_front() //删除c中首元素 c.erase(p) //删除迭代器p指向的元素 c.erase(b, e) //删除迭代器b和e之间的元素 c.clear() //删除c中的所有元素
pop_front和pop_back成员函数
而且这些操作的返回值是void,所以在弹出之前要保存好这个值
while(!ilist.empty()) { process(ilist.front()); //对ilist的首元素进行一些处理 ilist.pop_front(); //完成处理后删除元素 }
从容器内部删除一个元素
循环删除一个list中的所有奇数
list<int> lst={0,1,2,3,4,5,6,7,8,9}; auto it=lst.begin(); while(it != lst.end()) if(*it%2) //若为奇数 it=lst.erase(it); //删除此元素 else ++it;
特殊的forward_list操作
forward_list<int> flst={0,1,2,3,4,5,6,7,8,9}; auto prev=flst.before_begin(); //表示flst的“首前元素” auto curr=flst.begin(); //表示flst总的第一个元素 while(curr != flst.end()) { if(*curr%2) { curr=flst.erase_after(prev); //删除并移动curr位置 } else { prev=curr; ++curr; } }
该表容器的大小
使用resize来增大或缩小容器,和往常一样array不支持resize。
list<int> ilist(10, 42); //10个int:每个的值都是42 ilist.resize(15); //将5个值为0的元素添加到ilist的末尾 ilist.resize(25, -1); //将10个值为-1的值加到末尾 ilist.resize(5); //从末尾删除20个元素
好的我们要知道对容器的操作会改变迭代器的有效性!!!
看程序!!!
//傻瓜循环,删除偶数元素,复制每个奇数元素 vector<int> vi={0,1,2,3,4,5,6,7,8,9}; auto iter=vi.begin(); //调用begin而不是cbegin,因为我们要改变vi while(iter != vi.end()) { if(*iter%2) { iter=vi.insert(iter, *iter); //复制当前元素,插在前面,返回指向新加的元素的 //迭代器 iter+=2; } else { iter=vi.erase(iter); //删除偶数元素 //不应该向前移动迭代器,iter指向我们删除之后的元素 } }
PS:不干了,尼玛这太长了,先让我好好消化一下,而且马上就考试了,忙死啦!!!!我要坚持不下了!!!