STL 容器(vector 和 list )
1.这个容器的知识点比较杂
迭代器的理解:
1.erase()函数的返回值,它的迭代器在循环遍历中的奇特之处;
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>
#include <functional> using namespace std; /*
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 99};
要求:
(1)将ia复制到一个vector容器vec中和一个list容器中lst中。
(2)将vec容器中的奇数值元素删除。
(3)使用内置算法计算vec窗器所有元素的和。Accumulate
(4)使用内置算法计算lst容器中大于5的元素的个数 count_if */ //lambda 表达式
// [](参数列表)->返回值 {函数体} void print(int val) //回调函数
{
cout << val << " ";
}
//打印的三种方式(回调函数、函数对象、兰巴达表达式)
struct PRINT
{
void operator()(int val)
{
cout << val << " ";
}
};
void printVec(vector<int>& v)
{
for_each(v.begin(), v.end(), [](int val){cout << val << " "; }); //采用兰博打表达式
cout << endl;
} void printList(list<int>& L) //这里采用了回调函数,函数对象
{
//for_each(L.begin(), L.end(), PRINT()); //回调函数对象
for_each(L.begin(), L.end(), print); //回调函数
cout << endl;
} class isGreat
{
public:
bool operator()(int val)
{
if (val > )
return true;
else
return false;
}
};
void test04(int* arr, int len)
{
vector<int> v1;
list<int> l1;
v1.assign(arr, arr + len - ); //将数组中的元素拷贝进容器中(第一种方法)
//将一个容器中的元素拷贝进另一个容器(第二种方法)
for (int val : v1) //C++11的表达式;此处的v1可以是数组或容器
{
l1.push_back(val);
}
//打印
printVec(v1);
printList(l1); //(2)将vec容器中的奇数值元素删除。 erase
vector<int>::iterator it = v1.begin();
for (; it != v1.end(); )
{
if (*it % != )
{
it = v1.erase(it); //这里关注 erase 的返回值,是一个迭代器。
//it--; //这种方法不对,有bug;它是将迭代器的移动还放在for循环的位置(正常放置),但是当第一个元素符合条件时,这种方法就出错,因为迭代器减小后,就越界了。
}
else //同时还有这步,将迭代器的移动放到下面。(这种属于通用方法,但是我还没有想懂,它删除后迭代器是如何移动的)(现在搞懂了,在线面有详细描述)
{
it++;
}
}
printVec(v1); //(3)使用内置算法计算vec窗器所有元素的和。Accumulate
auto it1 = v1.begin(); //auto可以自动推导变量的类型。
auto sum = accumulate(it1, v1.end(), ); //第三个参数为:求和的基数;即容器中所有的元素的和加上它就是最后的总和。 //(4)使用内置算法计算lst容器中大于5的元素的个数
int num = count_if(l1.begin(), l1.end(), isGreat());
cout << num << endl;
} int main()
{
int ia[] = { , , , , , , , , , , };
int len = sizeof(ia) / sizeof(int);
test04(ia, len); system("pause");
return EXIT_SUCCESS;
}
1.这个题 的知识点:
1)vector容器在遍历的时候删除元素;这个和 erase()函数的返回值有关
2) erase()函数的返回值;(这个最重要)
3)一个容器中元素拷贝到不同类型的容器中(三种方法,一种没写,为普通的for循环遍历)
4)打印容器元素的三种方法:(回调函数,函数对象,兰巴达表达式)
5)STL的求和函数 accumulate(),第三个参数的作用;
6)auto类型;可以自动推导变量的类型
7)查找count_if()函数的使用,第三个参数的作用。
2.循环遍历,it++放置不同的位置;
1)在正常的for循环位置
1)符合条件时erase()容器中的某个元素,但是没有接返回值
2)符合条件时erase()容器中的某个元素,接了返回值;
3)符合条件时,接了返回值,同时在下面接着 it--;看容器首位元素符合条件和不符合条件的两种情况。
2)不放在正常位置
1)放在不符合条件的情况下it++;(即正确的情况,上面的那段代码)。
void test01(vector<int> v)
{ //这段代码会报错,因为当进行 erase() 后, 当前迭代器就失效了。而这里对它进行了++操作,所以程序崩溃
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
if (*it % != )
{
v.erase(it);
}
}
} void test02(vector<int> v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{ //这段代码也会崩溃,erase()函数的返回值被接收,此时假如最后一个数据也符合条件,代码运行到最后的数据,也会崩溃。
if (*it % != )
{
it = v.erase(it);
}
}
} for (vector<int>::iterator it = v.begin(); it != v1.end(); it++)
{
cout << *it << " ";
if (*it % != )
{
v1.erase(it); //这里关注 erase 的返回值,是一个迭代器。如果接受这个迭代器,那么此时它就指向删除元素的下一个元素。
it--; //这种方法不对,有bug;它是将迭代器的移动还放在for循环的位置(正常放置),但是当第一个元素符合条件时,这种方法就出错,因为迭代器减小后,就越界了。
} //但是假如第一个数据不符合条件就没有问题。
}
/*
vector<int> 容器 erase() 的返回值为"当前位置的"迭代器;它是这样理解的;假如你不接返回值,那么遍历循环时,删除后的当前迭代器
值失效,而你接下来还对它进行了操作,编译器马上段错误。
当你对它的返回值接收后,(就像紧密排列在一起的球,拿掉其中的一个,下一个立刻补上,);虽然返回的是同一个位置的迭代器,但是它
值已经发生变化,(相对于原来的容器来说,他就返回了属于后一个值得迭代器。)而这个迭代器是有效的,你可以对它进行操作。(但是此时
还有一些额外情况,例如:当容器最后一个数据符合条件,它的迭代器被删除,而又被接到返回值,此时这个迭代器就是尾部的 end()迭代器,
假如遍历的循环,第三个条件还写在与原来的位置,如(++操作),此时就会发生迭代器的越界,编译器出现段错误。(在下面有实例)。 */
3.sort算法排序【包含:函数对象(仿函数)】;
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<string>
using namespace std; //sort排序算法
struct for_each_condition{
void operator()(int val){
cout << val << " ";
}
};
void test01(){ vector<int> v;
v.push_back();
v.push_back();
v.push_back();
v.push_back();
v.push_back();
v.push_back(); for_each(v.begin(), v.end(), for_each_condition()); cout << endl;
sort(v.begin(), v.end(), less<int>());
for_each(v.begin(), v.end(), for_each_condition()); cout << endl;
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), for_each_condition()); cout << endl;
} class Person{
public:
Person(string name, int age){
this->mName = name;
this->mAge = age;
}
bool operator==(const Person& p){
if (p.mName == this->mName && this->mAge == p.mAge){
return true;
}
return false;
}
public:
string mName;
int mAge;
}; //排序对象
struct for_each_condition_obj{
void operator()(Person& val){
cout << "Name:" << val.mName << " Age:" << val.mAge << endl;
}
};
struct sort_condition{
bool operator()(Person& p1, Person& p2){
return p1.mAge > p2.mAge;
}
};
void test02(){ vector<Person> v;
v.push_back(Person("john01", ));
v.push_back(Person("john03", ));
v.push_back(Person("john05", ));
v.push_back(Person("john02", ));
v.push_back(Person("john06", ));
v.push_back(Person("john03", )); for_each(v.begin(), v.end(), for_each_condition_obj()); cout << endl;
sort(v.begin(), v.end(), sort_condition());
for_each(v.begin(), v.end(), for_each_condition_obj()); cout << endl;
}
int main(){ //test01();
test02(); system("pause");
return EXIT_SUCCESS;
}
STL 容器(vector 和 list )的更多相关文章
- 从零开始写STL—容器—vector
从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...
- [C++]STL容器Vector的内存释放
直接抛出两句话,说明到底应该如何释放Vector占用的内存. “vector的clear不影响capacity,你应该swap一个空的vector.” <Effective STL>中的“ ...
- STL容器vector应用注意事项
[1]提前分配足够空间以免不必要的重新分配和复制代价 关于vector容器重新分配和复制及析构释放的代价,请参见随笔<STL容器之vector>. 应用示例对比代码如下: #include ...
- STL容器 vector,list,deque 性能比较
C++的STL模板库中提供了3种容器类:vector,list,deque对于这三种容器,在觉得好用的同时,经常会让我们困惑应该选择哪一种来实现我们的逻辑.在少量数据操作的程序中随便哪一种用起来感觉差 ...
- STL容器 -- Vector
核心:Vector 是 STL 里的一个向量容器,可以像数组那样进行随机访问,能在尾部插入元素,对于元素的删除和插入可以动态管理内存. 头文件: #include <vector> 构造函 ...
- STL - 容器 - vector简单应用
VectorTest.cpp #include <vector> #include <iostream> #include <string> #include &l ...
- ACM常用STL容器
// STL(标准模板库),由三大部分组成:容器,算法,迭代器 // STL六大组件:container(容器),algorthm(算法),iterator(迭代器) // function obje ...
- 跟我一起学STL(2)——vector容器详解
一.引言 在上一个专题中,我们介绍了STL中的六大组件,其中容器组件是大多数人经常使用的,因为STL容器是把运用最广的数据结构实现出来,所以我们写应用程序时运用的比较多.然而容器又可以序列式容器和关联 ...
- 【转】c++中Vector等STL容器的自定义排序
如果要自己定义STL容器的元素类最好满足STL容器对元素的要求 必须要求: 1.Copy构造函数 2.赋值=操作符 3.能够销毁对象的析构函数 另外: 1. ...
- 带你深入理解STL之Vector容器
C++内置了数组的类型,在使用数组的时候,必须指定数组的长度,一旦配置了就不能改变了,通常我们的做法是:尽量配置一个大的空间,以免不够用,这样做的缺点是比较浪费空间,预估空间不当会引起很多不便. ST ...
随机推荐
- Codeforces Gym 100269K Kids in a Friendly Class 构造题
Kids in a Friendly Class 题目连接: http://codeforces.com/gym/100269/attachments Description Kevin resemb ...
- mysql远程表/视图-应用
Date :20140213Auth: Jin参考http://blog.sina.com.cn/s/blog_757b0e130101erl5.htmlhttp://dev.mysql.com/do ...
- [漏洞检测]Proxpy Web Scan设计与实现(未完待续)
Proxpy Web Scan设计与实现 1.简介: Proxpy Web Scan是基于开源的python漏洞扫描框架wapiti改造的web漏洞扫描器,其主要解决以下几个问题而生 ...
- window安装svn
window安装svn 1 安装时,安装路径选择好,把打X的都选上,默认第一个 安装完毕后,安装语言包,完毕,电脑上右键打开svn,,svn设置,常规设置,选中文 官网就有的下的 2 创建版本库,检出 ...
- 【mysql】mysql增加version字段实现乐观锁,实现高并发下的订单库存的并发控制,通过开启多线程同时处理模拟多个请求同时到达的情况 + 同一事务中使用多个乐观锁的情况处理
mysql增加version字段实现乐观锁,实现高并发下的订单库存的并发控制,通过开启多线程同时处理模拟多个请求同时到达的情况 ==================================== ...
- Wishbone接口Altera JTAG UART
某些时候,我们在使用Altera FPGA的时候,尤其是涉及SoC系统的时候,通常需要一个串口与PC交互.使用Altera的USB-Blaster免去了外接一个串口.我们可以使用下面所述的IP核通过U ...
- python wheel 包命名规则和 abi 兼容
wheel 包的命名规定 wheel 包的命名格式为 {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform ...
- pymongo 目标计算机积极拒绝
今天在使用pymongo连接服务器上的mongodb数据库时出现该问题 其实原因是mongodb本身配置只允许本机连接数据库 打开mongod.conf即mongodb的配置文件 一般来说是vim / ...
- in_array() 和array_search的区别
在判断字符串是否在某个数组里面的时候,我们会经常用到in_array()和array_search这两个函数. 他们的用法都是在数组中搜索给定的值,但是不同的是, in_array()给定的值 val ...
- [Functional Programming ADT] Create a Redux Store for Use with a State ADT Based Reducer
With a well defined demarcation point between Redux and our State ADT based model, hooking up to a R ...