创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作:

1. set(string key, string value, int timestamp)

  • 存储键 key、值 value,以及给定的时间戳 timestamp

2. get(string key, int timestamp)

  • 返回先前调用 set(key, value, timestamp_prev) 所存储的值,其中 timestamp_prev <= timestamp
  • 如果有多个这样的值,则返回对应最大的  timestamp_prev 的那个值。
  • 如果没有值,则返回空字符串("")。

示例 1:

输入:inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]]
输出:[null,null,"bar","bar",null,"bar2","bar2"]
解释: 
TimeMap kv;  
kv.set("foo", "bar", 1); // 存储键 "foo" 和值 "bar" 以及时间戳 timestamp = 1  
kv.get("foo", 1); // 输出 "bar"  
kv.get("foo", 3); // 输出 "bar" 因为在时间戳 3 和时间戳 2 处没有对应 "foo" 的值,所以唯一的值位于时间戳 1 处(即 "bar")  
kv.set("foo", "bar2", 4);  
kv.get("foo", 4); // 输出 "bar2"  
kv.get("foo", 5); // 输出 "bar2"  

示例 2:

输入:inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]]
输出:[null,null,null,"","high","high","low","low"]

提示:

  1. 所有的键/值字符串都是小写的。
  2. 所有的键/值字符串长度都在 [1, 100] 范围内。
  3. 所有 TimeMap.set 操作中的时间戳 timestamps 都是严格递增的。
  4. 1 <= timestamp <= 10^7
  5. TimeMap.set 和 TimeMap.get 函数在每个测试用例中将(组合)调用总计 120000 次。
#include <iostream>
#include <vector>
#include <tuple>
#include <string>
#include <numeric>
#include <map> using namespace std; //vector<tuple<string, string, int> > vec;
//auto iter = back_inserter(vec);
//vector<pair<string, map<string, int> > > vec;
//auto iter = back_inserter(vec);
//multimap<string, map<string, int> > mun; class TimeMap {
public:
TimeMap(){
ios_base::sync_with_stdio(false);
cin.tie();
} void set(string key, string value, int timestamp) {
mun[key].insert(map<int, string>::value_type(timestamp, value));//存储set()函数的参数值
} string get(string key, int timestamp) {
auto iter = mun[key].upper_bound(timestamp);
/*这里使用了二分法,并且这里必须使用upper_bound(),
因为题中有“如果有多个这样的值,则返回对应最大的timestamp_prev的那个值。”这个条件
iter的位置,恰好是最大值的下一个位置
*/
return iter == mun[key].end() ? prev(iter)->second : (iter == mun[key].begin() ? "" : prev(iter)->second);
/*这里也可以使用 return iter == mun[key].begin() ? "" : prev(iter)->second; 不过个人认为不好理解*/
/*使用上面这种方法:表示如果在map容器中没有找到不小于timestamp的值,表示map容器中的值都满足题目,
则我们只需要取前一位置的值。
如果找到了,则我们首先需要判断,找到的位置是不是在map的第一个位置,如果在,则表示map中的元素都不满足题目,则输出""
如果不在,表示iter前一位置的值是满足题目的。
*/
}
private:
map<string, map<int, string> > mun;//存储set()函数的map容器
};
int main()
{
TimeMap kv;
kv.set("foo", "bar", ); // 存储键 "foo" 和值 "bar" 以及时间戳 timestamp = 1
cout << kv.get("foo", ) << " "; // 输出 "bar"
cout << kv.get("foo", ) << " "; // 输出 "bar" 因为在时间戳 3 和时间戳 2 处没有对应 "foo" 的值,所以唯一的值位于时间戳 1 处(即 "bar")
kv.set("foo", "bar2", );
cout << kv.get("foo", ) << " "; // 输出 "bar2"
cout << kv.get("foo", ) << " "; // 输出 "bar2" system("PAUSE");
return ;
}

LeetCode 981.基于时间的键值存储(C++)的更多相关文章

  1. [Swift]LeetCode981. 基于时间的键值存储 | Time Based Key-Value Store

    Create a timebased key-value store class TimeMap, that supports two operations. 1. set(string key, s ...

  2. 【插件开发】—— 8 IPreferenceStore,插件的键/值存储!

    前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 5 SWT简单控件的使用与布局搭配 6 SWT复杂空间与布局搭配 7 SWT布局详解 ...

  3. 用于C# 的异步,持久的键值存储 Akavache 使用

    Akavache是​​一个异步的,持久的(即写入磁盘)键值存储,用于在C#中编写桌面和移动应用程序,基于SQLite3.Akavache非常适合存储重要数据(即用户设置)以及过期的缓存本地数据. 开源 ...

  4. SQLite实现内存键值存储

    SQLite数据文件往Linux内存文件系统/dev/shm/data.sqlite3一放,就是内存级读写性能的SQL系统.用SQLite实现内存键值存储:CREATE TABLE IF NOT EX ...

  5. CockroachDB学习笔记——[译]CockroachDB中的SQL:映射表中数据到键值存储

    CockroachDB学习笔记--[译]CockroachDB中的SQL:映射表中数据到键值存储 原文标题:SQL in CockroachDB: Mapping Table Data to Key- ...

  6. PowerDotNet平台化软件架构设计与实现系列(05):ETCD分布式键值存储平台

    ETCD目前在PowerDotNet已经被用于注册中心和配置管理(常见的配置中心在PowerDotNet中仅仅是一个小小的模块而已)中,作为基础设施的重要组成部分,ETCD的重要性不言而喻. 本文简单 ...

  7. Key-Value键值存储原理初识(NOSQL)

    NO-Sql数据库:Not Only不仅仅是SQL 定义:非关系型数据库:NoSQL用于超大规模数据的存储.(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据).这些类型的数据存储不需要固 ...

  8. LeetCode 677. Map Sum Pairs 键值映射(C++/Java)

    题目: Implement a MapSum class with insert, and sum methods. For the method insert, you'll be given a ...

  9. [iOS Keychain本地长期键值存储]

    目前本地存储方式大致有:Sqlite,Coredata,NSUserdefaults.但他们都是在删除APP后就会被删除,如果长期使用存储,可以使用Keychain钥匙串来实现. CHKeychain ...

随机推荐

  1. win10开机时不显示锁屏壁纸

    win10开机壁纸存放在此目录下: C:\Users\%username%\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManage ...

  2. 抽象类(abstract class)和接口(Interface)的区别

    前言 抽象类(abstract class)和接口(Interface)是Java语言中对于抽象类定义进行支持的两种机制,赋予了Java强大的面向对象能力. 二者具有很大的相似性,甚至可以相互替换,因 ...

  3. git commit失败

    1.使用命令  git rm test.txt 删除版本库中文件, 下一步:git commit 提交 出现如图: 这是因为没有同时提交信息,即:git commit -m "这里是信息&q ...

  4. Vue.js 60分钟快速入门

    原文链接:http://www.cnblogs.com/keepfool/p/5619070.html Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和 ...

  5. left jion on和where条件的区别

    1.on是在生成临时表时()起作用,而且不管on中的条件是否为真,都会返回(left join)左边所有的数据,如果不匹配也是返回空. 2.where 是在生成了临时表后,再对表进行过滤 个人理解:先 ...

  6. 获取WPF窗体/控件的句柄/当前进程的句柄

    1.在WPF中,获取当前窗体的句柄与WINFORM中不一样: WINFORM直接获取:this.Handle----------this是窗体的类名,handle就是句柄. 2.WPF中先引用命名空间 ...

  7. EOS 修改文件名称与文件夹名称

    最近有一个需求,需要修改EOS名称,将所有文件里面的EOS改为UOS,文件夹名称也需要修改,然后重新构建项目,于是写了一个小程序进行修改.如果有相同项目类似的修改,可以在下面这个程序稍做修改就可以了. ...

  8. Runtime常用的几个应用场景

    Runtime常见的几个应用场景. Runtime常见应用场景 具体应用拦截系统自带的方法调用(Method Swizzling黑魔法) 实现给分类增加属性 实现字典的模型和自动转换 JSPatch替 ...

  9. FileWriter 中午乱码

      解决办法 BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (fil ...

  10. C语言中的预处理命令

    预处理功能是C语言的重要功能. 问:为什么要预处理,什么是预处理? 答:我们知道高级语言的运行过程是通过编译程序(编译器)把源代码翻译成机器语言,实现运行的.编译程序的工作包含:语法分析.词法分析.代 ...