您的位置:首页 > 编程语言 > C语言/C++

关于c++中的STL的学习与再认识(三)

2015-07-29 16:45 549 查看
上一篇讲了经常用到和非常重要的迭代器。

Vertor中的数据操作

可以用insert()函数往Vertor中插入一个元素:

int n[] = { 22, 33, 11, 44, 55, 66, 99, 55, 88 };
vector<int> v1(n, n + 9);
vector<int> v2(n, n + 2);
vector<int>::iterator it = v1.begin();
v1.insert(it + 1, 31);  //22, 31, 33, 11, 44, 55, 66, 99, 55, 88


**特别注意:**insert()函数返回值类型并不是void,而是返回一个迭代器,此时的it值会改变,指向一块不清楚的内存,将不在是v1.begin();因此以下用法会出错。

v1.insert(it + 1, 31);  //22, 31, 33, 11, 44, 55, 66, 99, 55, 88
v1.insert(it, 32);


第一次插入正确,之后it将不在指向初始迭代器,出错。想继续插入的情况下,必须为insert()函数设置返回值。

it = v1.insert(it + 1, 31);  //22, 31, 33, 11, 44, 55, 66, 99, 55, 88
v1.insert(it, 32);//22, 32, 31, 33, 11, 44, 55, 66, 99, 55, 88


此外,insert()函数还有以下用法:

int n[] = { 22, 33, 11, 44, 55, 66, 99, 55, 88 };
vector<int> v1(n, n + 9);
vector<int> v2(n, n + 2);
vector<int>::iterator it = v1.begin();
it = v1.insert(it + 1, 31);  //22, 31, 33, 11, 44, 55, 66, 99, 55, 88
it = v1.insert(it, 32);//22, 32, 31, 33, 11, 44, 55, 66, 99, 55, 88
it = v1.insert(it, 3, 100);//22,100,100,100 32, 31, 33, 11, 44, 55, 66, 99, 55, 88
it = v1.insert(it, all(v2));//22, 22, 33 ,100,100,100 32, 31, 33, 11, 44, 55, 66, 99, 55, 88

it = v1.erase(v1.begin() + 1);  //22, 33 ,100,100,100 32, 31, 33, 11, 44, 55, 66, 99, 55, 88  *it = 33;
it = v1.erase(v1.begin() + 3, v1.begin() + 5); //22, 33 ,100 32, 31, 33, 11, 44, 55, 66, 99, 55, 88  *it = 32;
cout << *it << endl;


在指定地方插入多个相同的值,返回多个插入值的第一个的位置;

在指定地方插入某一区间的值;

erase()函数:

删除指定位置的一个数,返回删除后第一个数的下标;

删除指定区间的数据,返回删除后第一个数的下标;

切记有返回值

具体实例看代码。

Set

容器特性:

* 添加一个元素,若元素已存在,舍弃;

* 移除元素

* 获取元素个数(不同元素的个数)

* 检测集合中是否存在某个元素

#include <iostream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <set>
using namespace std;

void print_set(set<int> s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
cout << *it << "  ";
cout << endl;
}

int main()
{
set<int> s;
for (int i = 1; i < 10; i++)
s.insert(i);
print_set(s);    //1, 2, 3, 4, 5, 6, 7, 8, 9
s.insert(10);      //1, 2, 3, 4, 5, 6, 7, 8, 9,10
s.insert(11);   //1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
s.erase(10);    //1, 2, 3, 4, 5, 6, 7, 8, 9,11
s.erase(s.find(2), s.find(4));  //1, 2, 3, 4, 5, 6, 7, 8, 9, 11
print_set(s);
cout << s.size() << endl; //8

cout << endl;
system("pause");
return 0;

}


在O(log N)(N是set中对象的个数)的时间复杂度下添加,移除元素,并检测元素时候存在

常数时间复杂度O(1)返回set的元素个数

set没有push_back()函数,因为set中元素的添加顺序不是很重要。insert()最常用的是插入一个元素,返回这个元素的迭代器和一个布尔值(是否插入成功)

set不是线性容器,不能用下标获取set的值。遍历set元素的唯一方法是使用迭代器(print_set函数)

关于find()函数:有一个全局find(),输入两个迭代器和一个元素,时间复杂度为O(N)。但set和map(包括multiset,hash_map)中搜索元素时,不要使用全局find(),而应该使用
set::find()

4000
时间复杂度为O(logN)。

set中没有排序函数。set有一个区间构造函数。

vector<int> v;

set<int> s(all(v));
vertor<int> v2(all(s));


上述中,v2与s包含相同元素,并且移除了v中重复的元素,可以对v2进行排序。任何可比较的元素都可以存储在set中。

Map

#include <iostream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <set>
#include <map>
using namespace std;

void print_map(map<string ,int> m)
{
for (map<string, int>::iterator it = m.begin(); it != m.end(); it++){
cout << it->second << "  ";
}
cout << endl;
}

int main()
{
map<string, int> m;
m["first"] = 1;
m["second"] = 2;
m["third"] = 3;
int sum = m["first"] + m["third"];
cout << sum << endl;  //4
cout << m.find("second")->second << endl;  //2
cout << (*m.find("second")).second << endl;  //2
print_map(m);

system("pause");
return 0;

}


可以看到:map和set非常像,只是它包含的不只是值,而是键值对
pair<key,value>
.Map保证最多只有一个键值拥有指定键。

* 遍历map只能用迭代器,迭代器是键值对,用it->second来取值。

* 非常相爱那个python中字典。

注意事项:

从内部看,map 和 set 几乎都是以红黑树的结构存储。要记住的是,遍历容器时 map 和 set 的元素总是按升序排列。而这也是为何在遍历 map 或 set时,极力不推荐改变键值的原因:如果所做的修改破坏了元素间的顺序,这至少会导致容器的算法失效。

常用算法

大部分算法都生声明在标准头文件
#include<algorithm>
。首先,STL提供了三种很简单的算法:min(a,b),max(a ,b ),swap(a,b)。

比较常用的有sort()函数:sort(begin, end) 按升序对一个区间的元素进行排序。注意,sort() 需要随机存取迭代器,因此它不能作用在所有类型的容器上。

find():find()。调用 find(begin, end, element) 返回‘element’首次出现时对应的迭代器,如果找不到则返回 end。和 find(…) 相反,count(begin, end, element) 返回一个元素在容器或容器的某个范围内出现的次数。

特别建议

在编写程序的过程中,模板列表能简化代码的阅读。

typedef vector<int> vi;
typedef vector<vi> vii;
typedef pair<int, int> ii;
#define sz(a) int(a.size()) //求对象a的大小
#define pb push_back
#define all(c) c.begin(),c.end()  //注意,all(c)后无括号
#define present(c,x) ((c).find(x) != (c).end())  //元素x存在与c中,用于set,map等
#define cpresent(c,x) (find(all(c),x) != (c).end())  //通用算法find,适用于全部容器,时间复杂度O(n)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vector 迭代器