#141. 数据结构-vector动态数组

数据结构-vector动态数组

知识点:

vector 是一种存储数据的容器,和平时使用的数组很像,可以存储一组相同类型的数据,下标默认从0开始,优点是长度可以动态改变,各种操作方法配置齐全,使用很方便,缺点是速度略慢于普通数组。

vector的创建:

vector<类型> 名字;
vector<int> v; // 创建一个int类型一维的空动态数组
vector<int> v(n,x); // 创建一个int类型一维动态数组,初始长度n,值为x。
vector<int> v[N]; // 创建一个int类型二维的动态数组,其中一维长度为N,二维长度可变
vector<vector<int>> v(n,vector<int>(m,x)) // 创建一个int类型n行m列的二维动态数组,初始值为x

vector的常用操作函数:

vector<int> v;
v.push_back(x); // 把元素x添加到末尾
v.pop_back(); // 把末尾元素删除
v.size(); // 返回长度
v[i]; // 获取下标为 i 的元素
v.front(); // 获取首位元素,也可以使用下标 v[0]
v.back(); // 获取末尾元素,也可以使用下标 v[v.size()-1]
v.clear(); // 清空容器
v.begin(); // 返回一个迭代器,指向容器的第一个元素
v.end(); // 返回一个迭代器,指向容器的最后一个元素的后一位
v.erase(v.begin()+1, v.begin()+4); // 删除容器中下标 1~4 的元素,删除的时间复杂度是O(n)

vector的循环遍历与输入输出:

(1) 往空数组添加元素
vector<int> v;
for (int i = 0; i < n; i++)
{
  int x; cin >> x;
  v.push_back(x); // 通过push_back往末尾添加n个数
}

(2) 提前声明数组大小,可以类似普通数组用下标输入
vector<int> v(n+1); // n+1是为了从1号下标开始存数据
for (int i = 1; i <= n; i++) cin >> v[i];

(3) 循环输出vector的元素
for (int i = 0; i < v.size(); i++) cout << v[i];

(4) 枚举型遍历
for (auto it : v) cout << it;

(5) 排序vector
sort(v.begin(), v.end())

(6) 对vector排序并去重
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end()); // unique函数必须先排序才能起到去重效果

练习:请使用vector完成下面的题目

有N个数组,初始时N个数组均为空。共有M次操作,每次在第X个数组中加入数字Y。问最终各数组中有多少数,并将它们排序输出。 比如,输入如下数据:

3 5
1 3
1 2
1 1
2 1
3 1

表示有3个数组,共有5次操作,分别向第1个数组存入3,第1个数组存入2,第1个数组存入1,第2个数组存入1,第3个数组存入1。

输出如下:

3 1 2 3
1 1
1 1

第1行表示:第1个数组中有3个数,排序结果为1 2 3

第2行表示:第2个数组中有1个数,排序结果为1

第3行表示:第3个数组中有1个数,排序结果为1

输入格式

第一行两个整数N、M(N≤100000,M≤300000)。
接下来M行,每行两个整数X、Y,含义见试题描述。(1≤X≤N,Y≤10^9)

输出格式

共N行,第i行第一个数SUM,表示第i个数组数的个数,接下来SUM个数,为排序之后的数组。

样例

3 5
1 3
1 2
1 1
2 1
3 1
3 1 2 3
1 1
1 1