12
返回列表 发新帖
楼主: 14417335
跳转到指定楼层
上一主题 下一主题
收起左侧

[高频题] 数组Snapshot

🔗
BridgeHUHX 2019-3-14 09:37:46 | 只看该作者
全局:
霍建华 发表于 2019-3-14 06:02
对着每个index 做一个treemap即可

get o1

那每个index需要copy所有snapshot的值吗?比如
snap 0 {1,2,3}
set(1, 20).  //index 1's value becomes to 20
snap 1 {1,20,3}
set(2, 30). //index 2's value becomes to 30
snap 2 {1,20,30}
好像我遇到的不太一样,他和我说的是每次set都会生成一个新的snapshot,所以是上面这种变化。

get(2) //return 30 from current snapshot
get(2,1) //return 3 from snap 1
如果只对index存(snap, value),那么2->(0, 3), (2, 30),(1, 3)这个在生成snap 1的时候需不需要copy呢?需要的话空间上和二维数组一样,时间上也是要把其他所有的copy一份。不copy的话get(2,1)怎么得到3呢?
回复

使用道具 举报

🔗
kaipeng21 2019-3-18 07:58:07 | 只看该作者
全局:
用Python 写了两种版本,第一种存仅更新改变的Version减缓内存,Get 用二分法查找.第二种做了点改变,每1024个 Frame把整个数组复制一遍,查找先用哈希再用二分快一些,牺牲了点内存,多久复制整个数组可以随状况自订改变

您好!
本帖隐藏的内容需要积分高于 200 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 200 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies


补充内容 (2019-3-18 08:01):
忘了用插入代码. . .
回复

使用道具 举报

🔗
kaipeng21 2019-3-18 07:59:37 | 只看该作者
全局:
第二种

您好!
本帖隐藏的内容需要积分高于 220 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 220 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

全局:
这是关系数据库的snapshot Isolation的simple
naive实现呀!
回复

使用道具 举报

🔗
testwe 2019-4-18 01:32:21 | 只看该作者
全局:
简单的写了下数组的。 基本思想是:
  • 维护一个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


  1. #include <algorithm>
  2. #include <cassert>
  3. #include <vector>

  4. using namespace std;

  5. template <typename ValueType>
  6. class VersionedArray {
  7. public:
  8.   using Version = size_t;

  9.   // default_val is the default value when an element doesn't exist.
  10.   explicit VersionedArray(size_t size, ValueType default_val)
  11.       : v_(size), default_val_(default_val) {}

  12.   void Set(size_t pos, ValueType val) {
  13.     assert(pos < v_.size());

  14.     if (v_[pos].empty() || v_[pos].back().first != ver_) {
  15.       v_[pos].push_back({ver_, val});
  16.     } else {
  17.       v_[pos].back().second = val;
  18.     }
  19.   }

  20.   int Get(size_t pos, Version ver) {
  21.     assert(pos < v_.size());
  22.     if (v_[pos].empty()) {
  23.       return default_val_;
  24.     }

  25.     // Find a version > ver, then the previous version is what we want.
  26.     auto it = upper_bound(
  27.         v_[pos].begin(), v_[pos].end(), make_pair(ver, -1),
  28.         [](const pair<Version, int>& v1, const pair<Version, int>& v2) {
  29.           return v1.first < v2.first;
  30.         });
  31.     if (it == v_[pos].begin()) {
  32.       return default_val_;
  33.     }
  34.     return prev(it)->second;
  35.   }

  36.   void TakeSnapshot() { ver_++; }

  37.   Version LatestVersion() const { return ver_; }

  38. private:
  39.   vector<vector<pair<Version, ValueType>>> v_;
  40.   Version ver_ = 0;
  41.   const ValueType default_val_;  // Default value when an element doesn't exist.
  42. };

  43. int main(int, char*[]) {
  44.   constexpr int NOT_FOUND = numeric_limits<int>::min();
  45.   VersionedArray<int> va(10, NOT_FOUND);
  46.   va.Set(0, 0);
  47.   assert(va.Get(0, va.LatestVersion()) == 0);
  48.   assert(va.Get(1, va.LatestVersion()) == NOT_FOUND);

  49.   va.TakeSnapshot();  // Now latest version is 1

  50.   va.Set(0, 10);
  51.   va.Set(1, 11);
  52.   va.Set(1, 111);

  53.   assert(va.Get(0, 0) == 0);
  54.   assert(va.Get(0, 1) == 10);
  55.   assert(va.Get(1, 0) == NOT_FOUND);
  56.   assert(va.Get(1, 1) == 111);

  57.   va.Set(1, 1111);

  58.   va.TakeSnapshot();  // Now latest version is 2
  59.   va.TakeSnapshot();  // Now latest version is 3
  60.   va.TakeSnapshot();  // Now latest version is 4
  61.   assert(va.Get(0, 0) == 0);
  62.   assert(va.Get(0, 1) == 10);
  63.   assert(va.Get(0, 2) == 10);
  64.   assert(va.Get(0, 3) == 10);
  65.   assert(va.Get(0, 4) == 10);

  66.   assert(va.Get(1, 0) == NOT_FOUND);
  67.   assert(va.Get(1, 1) == 1111);
  68.   assert(va.Get(1, 2) == 1111);
  69.   assert(va.Get(1, 3) == 1111);
  70.   assert(va.Get(1, 4) == 1111);

  71.   return 0;
  72. }
复制代码






补充内容 (2019-4-18 01:34):
Followup的map,和数组相比,基本类似

补充内容 (2019-4-18 01:35):
刚才补充了一句话,原来能高亮的代码排版全乱了。麻烦版主看到了帮忙修改一下代码的格式。

评分

参与人数 1大米 +1 收起 理由
xlblue + 1 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
hua88 2019-5-8 02:40:18 | 只看该作者
全局:
  1. class Snapshot:
  2.     def __init__(self, length):
  3.         if length<=0:
  4.             raise Exception("Invalid length %s"%length)
  5.         self.version = 1
  6.         self.dictionary = [{} for i in range(length)]


  7.     def setValue(self, index, value):
  8.         if 0<=index < len(self.dictionary):
  9.         
  10.             self.dictionary[index][self.version]=value
  11.         else:
  12.             raise Exception ("Invalid index %s"%index)


  13.    
  14.     def getValue(self, index, version):
  15.         if version not in self.dictionary[index]:
  16.             raise Exception ("Version %s not exist"%version)

  17.         return self.dictionary[index][version]

  18.    
  19.     def snap(self):
  20.         self.version = self.version+1

  21. sp = Snapshot(3)
  22. sp.setValue(1,1)

  23. sp.setValue(0,0)
  24. sp.setValue(2,2)
  25. sp.snap()
  26. sp.setValue(1,0)

  27. assert sp.getValue(1, 1) ==  1
  28. assert sp.getValue(1, 2) == 0




复制代码

回复

使用道具 举报

🔗
hua88 2019-5-8 10:59:58 | 只看该作者
全局:
  1. '''
  2. 如果题意中是要求如果输入了不存在的版本号返回最进的版本,那么就就要binary search key
  3. '''
  4. class Snapshot:
  5.     def __init__(self):
  6.         self.version = 1
  7.         self.keys = collections.defaultdict(list)
  8.         self.values = collections.defaultdict(list)


  9.     def setValue(self, index, value):
  10.         if  self.keys[index]  and self.version == self.keys[index][-1]:
  11.             self.values[index][-1]=value
  12.         else:
  13.             self.keys[index].append(self.version)
  14.             self.values[index].append(value)


  15.    
  16.     def getValue(self, index, version):
  17.         versions = self.keys[index]
  18.         versionIndex = bisect.bisect_right(versions, version)
  19.         if versionIndex:
  20.             
  21.             return self.values[index][versionIndex-1]
  22.         else:
  23.             return ""

  24.    
  25.     def snap(self):
  26.         self.version = self.version+1


  27. sp = Snapshot()
  28. #version 1
  29. sp.setValue(1,1)
  30. sp.setValue(1,2)
  31. sp.setValue(0,0)
  32. sp.setValue(2,2)
  33. sp.snap() #version 2
  34. sp.snap() #version 3
  35. sp.snap() #version 4
  36. sp.setValue(1,0)
  37. sp.setValue(2, 20)


  38. assert sp.getValue(1, 1) ==  2
  39. assert sp.getValue(1, 2) == 2
  40. assert sp.getValue(2, 7) == 20
  41. assert sp.getValue(1, 4) == 0
  42. assert sp.getValue(1, 3) == 2
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表