0%
实现比较简单直接看代码,说几点:
(i%MAX_SIZE+MAX_SIZE)%MAX_SIZE
是为了支持负数下标,如果不需要负下标可以直接i%MAX_SIZE
- 循环队列中,因为begin、end一直增加,所以不需要full标志仍然可以把空间用足,不存在队满和队空条件相同。
- 如果限定MAX_SIZE是2的幂,可以用
i&(MAX_SIZE-1)
来代替取模,而且同样支持负数下标,真是又快又好 _
- CircularArray的主要用途是在DP循环的时候如果状态仅依赖前N项,那么可以简单地把空间节省到N。
- Queue的用途是为了替代std::queue,但实际上std::queue已经相当快了。
总的来说这两个数据结构在比赛中基本用不到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| template<typename T, int MAX_SIZE> class CircularArray { T data[MAX_SIZE]; public: CircularArray(const T& t=T()) {fill(data, data+MAX_SIZE, t);} T& operator [] (int i) { return data[(i%MAX_SIZE+MAX_SIZE)%MAX_SIZE]; } };
template<typename T, int MAX_SIZE> class Queue { CircularArray<T, MAX_SIZE> data; int begin = 0; int end = 0; public: void push(const T& t) { assert(!full()); data[end++] = t; }
T pop() { assert(!empty()); return data[begin++]; }
T& peek() { assert(!empty()); return data[begin]; }
const T& peek() const { return const_cast<Queue*>(this)->peek(); }
bool empty() const { return end == begin; }
size_t size() const { return end-begin; }
bool full() const { return size() == MAX_SIZE; } };
|