Skip to content

Instantly share code, notes, and snippets.

@chengluyu
Created September 21, 2014 09:43
Show Gist options
  • Save chengluyu/a05553d4b996d59e9c18 to your computer and use it in GitHub Desktop.
Save chengluyu/a05553d4b996d59e9c18 to your computer and use it in GitHub Desktop.
Guidance to You

A Brief OI Practical Guidance


自由定义数组下标

比如我们要定义一个下标从 -1000 到 1000 (闭区间)的 int 类型数组,我们可以这样写:

int *a = new int[2001] + 1000;

解释:下标从 -1000 到 1000 (闭区间)意味着有 2001 个元素,我们先 new 一个长度为 2001 的数组,然后加上 1000 的偏移量,这样 a 指向的实际上是原数组的第 1001 个元素。

如果要定义很多这样的数组,我们不妨定义一个宏:

#define def_array(type, name, begin, end) type *name = new type[(end) - (begin) + 1] - (begin)

然后就可以用这个宏方便地定义这样的数组了,当然仅限于一维数组:

def_array(int, a, -1000, 1000);

什么时候该使用 STL 中的容器,什么时候不该

STL 中比较常用的容器有:vectormapqueuestackpriority_queueset。因为它们申请内存时都是动态申请,在 OI 中相对较慢,所以我们只在对性能要求不高的时候使用它们

具体的用途用法以后补充,可以先自己去找一下资料。


什么是迭代器

思考一下类似于链表、字符串、数组这样的线性数据结构,我们最常用的操作是什么?

答案当然是遍历(别说这个你都想不到-_-)。

并且当我们遍历链表、字符串、数组时,我们写的代码是不同的。

为什么?因为它们类型不一样。比如说 std::vector<int>int [] 是不同的类型,char []std::string 也是不同的类型。

但是我们有的时候要对它们做相同的操作,比如说每个元素加上一个值,把所有元素倒过来等等等等。

难道我们要为不同的类型都写一个专门的函数吗?但是要执行的操作明明是一样的。真是够了……

而迭代器就是为了解决这种问题的,它为顺序访问提供了一个统一的接口,使我们不用担心容器原本的类型。

那么统一的接口是什么呢?

迭代器好比一个游标,指向数组中的某个元素,我们可以向前或向后移动这个游标,使其指向前一个或者后一个元素。

举例: std::vector 的迭代器

如果 ivec 是一个元素类型为 intvector

std::vector<int> ivec;

我们可以这样获取它的首迭代器和尾迭代器:

std::vector<int>::iterator head = ivec.begin();
std::vector<int>::iterator tail = ivec.end();

std::vector<int>::iterator这一串长长的东西是什么?

这就是std::vector<int>的迭代器的类型,就是在原本的类型名后面加了个::iterator而已。STL 中其他的容器也是这样。

ivec.begin()就是获取ivec的首迭代器,ivec.end() 就是获取 ivec 的尾迭代器。同样,STL 中其他的容器也是这样。

头迭代器是指向第一个元素,那尾迭代器是指向最后一个元素吗?

不是。尾迭代器是指向最后一个元素后面的元素,是一个不存在的元素,它的作用只是作为一个标志,标志迭代器迭代的终点。这里你可能不明白,没事,我们看代码体会一下:

#include <iostream>
#include <vector>

using namespace std;

int main() {
  vector<int> ivec;
  
  for (int i = 0; i < 10; i++) {
    ivec.push_back(i);
  }

  for (vector<int>::iterator it = ivec.begin(); it != ivec.end(); ++it) {
    cout << *it << endl;
  }
  return 0;
}

这段代码它的输出就是从 0 到 9。

先写到这里。 To be continued.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment