高级农民
- 积分
- 2472
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2014-5-3
- 最后登录
- 1970-1-1
|
简单的写了下数组的。 基本思想是:
- 维护一个version num,TakeSnapshot时加1
- 数组的每个元素是一个{since_version, value} 的vector (保存的其实是the value since a version的信息)
- Get,O(log(那个元素不同版本的个数)),二分查找到想要的since_version即可,我这里用的是upper_bound的结果减1
- Set,O(1)。看看那个位置最新的version,如果和当前version相等,直接覆盖;否则append
- #include <algorithm>
- #include <cassert>
- #include <vector>
- using namespace std;
- template <typename ValueType>
- class VersionedArray {
- public:
- using Version = size_t;
- // default_val is the default value when an element doesn't exist.
- explicit VersionedArray(size_t size, ValueType default_val)
- : v_(size), default_val_(default_val) {}
- void Set(size_t pos, ValueType val) {
- assert(pos < v_.size());
- if (v_[pos].empty() || v_[pos].back().first != ver_) {
- v_[pos].push_back({ver_, val});
- } else {
- v_[pos].back().second = val;
- }
- }
- int Get(size_t pos, Version ver) {
- assert(pos < v_.size());
- if (v_[pos].empty()) {
- return default_val_;
- }
- // Find a version > ver, then the previous version is what we want.
- auto it = upper_bound(
- v_[pos].begin(), v_[pos].end(), make_pair(ver, -1),
- [](const pair<Version, int>& v1, const pair<Version, int>& v2) {
- return v1.first < v2.first;
- });
- if (it == v_[pos].begin()) {
- return default_val_;
- }
- return prev(it)->second;
- }
- void TakeSnapshot() { ver_++; }
- Version LatestVersion() const { return ver_; }
- private:
- vector<vector<pair<Version, ValueType>>> v_;
- Version ver_ = 0;
- const ValueType default_val_; // Default value when an element doesn't exist.
- };
- int main(int, char*[]) {
- constexpr int NOT_FOUND = numeric_limits<int>::min();
- VersionedArray<int> va(10, NOT_FOUND);
- va.Set(0, 0);
- assert(va.Get(0, va.LatestVersion()) == 0);
- assert(va.Get(1, va.LatestVersion()) == NOT_FOUND);
- va.TakeSnapshot(); // Now latest version is 1
- va.Set(0, 10);
- va.Set(1, 11);
- va.Set(1, 111);
- assert(va.Get(0, 0) == 0);
- assert(va.Get(0, 1) == 10);
- assert(va.Get(1, 0) == NOT_FOUND);
- assert(va.Get(1, 1) == 111);
- va.Set(1, 1111);
- va.TakeSnapshot(); // Now latest version is 2
- va.TakeSnapshot(); // Now latest version is 3
- va.TakeSnapshot(); // Now latest version is 4
- assert(va.Get(0, 0) == 0);
- assert(va.Get(0, 1) == 10);
- assert(va.Get(0, 2) == 10);
- assert(va.Get(0, 3) == 10);
- assert(va.Get(0, 4) == 10);
- assert(va.Get(1, 0) == NOT_FOUND);
- assert(va.Get(1, 1) == 1111);
- assert(va.Get(1, 2) == 1111);
- assert(va.Get(1, 3) == 1111);
- assert(va.Get(1, 4) == 1111);
- return 0;
- }
复制代码
补充内容 (2019-4-18 01:34):
Followup的map,和数组相比,基本类似
补充内容 (2019-4-18 01:35):
刚才补充了一句话,原来能高亮的代码排版全乱了。麻烦版主看到了帮忙修改一下代码的格式。 |
|