假设我有两个具有唯一ID的对象列表和一个确定其顺序的属性,那么如何有效地获取增量索引(插入了哪些索引,删除了哪些索引以及移动了哪些索引)?
输入示例:
let before: [(id: String, timestamp: String)] = [
("A", "2015-06-04T12:38:09Z"),
("B", "2015-06-04T10:12:45Z"),
("C", "2015-06-04T08:39:55Z"),
("D", "2015-06-03T23:58:32Z"),
("E", "2015-06-01T00:05:51Z"),
]
let after: [(id: String, timestamp: String)] = [
("F", "2015-06-04T16:13:01Z"),
("C", "2015-06-04T15:10:29Z"),
("A", "2015-06-04T12:38:09Z"),
("B", "2015-06-04T10:12:45Z"),
]
let delta = deltaFn(before, after)
上面是可视化的:
BEFORE AFTER
+-------+----+----------------------+ +-------+----+----------------------+
| index | id | timestamp | | index | id | timestamp |
+-------+----+----------------------+ +-------+----+----------------------+
| 0 | A | 2015-06-04T12:38:09Z | | 0 | F | 2015-06-04T16:13:01Z |
| 1 | B | 2015-06-04T10:12:45Z | | 1 | C | 2015-06-04T15:10:29Z |
| 2 | C | 2015-06-04T08:39:55Z | | 2 | A | 2015-06-04T12:38:09Z |
| 3 | D | 2015-06-03T23:58:32Z | | 3 | B | 2015-06-04T10:12:45Z |
| 4 | E | 2015-06-01T00:05:51Z | | - | | |
+-------+----+----------------------+ +-------+----+----------------------+
预期结果(增量):
Inserted indexes: [0]
Deleted indexes: [3, 4]
Moved indexes: [(from: 0, to: 2), (from: 1, to: 3), (from: 2, to: 1)]
可以通过使用2个映射(从每个元素的ID到其索引的映射)并将它们进行比较来解决。
对于哈希映射,时间复杂度为O(n),对于基于树的映射,时间复杂度为O(nlogn)。
伪代码:
map1 = empty map
map2 = empty map
for each element x with index i in before:
map1.insert(x,i)
for each element x with index i in after:
map2.insert(x,i)
//find moved and deleted:
for each key x in map1:
id1 = map1.get(x)
id2 = map2.get(x)
if id2 == nil:
add id1 to "deleted indexes"
else if id1 != id2:
add (id1,id2) to "moved indexes"
map2.delete(x)
//find new indexes:
for each key x in map2:
add map2.get(x) to "inserted indexes"
编辑 :(建议在评论中)
通过仅映射最小的列表,然后迭代数组(未映射)而不是映射,可以将O(min{m,n})
基于树的映射到的内存输出和时间减到最少(两个列表的大小O(max{m,n}log(min{m,n}))
在哪里m,n
)。
map = empty map
for each element x with index i in smaller list:
map.insert(x,i)
for each element x with index i1 in larger list:
i2 = map.get(x)
if i2:
if i1 != i2:
add (i2, i1) to "moved indexes" if smaller list is before
add (i1, i2) to "moved indexes" if smaller list is after
map.delete(x)
else:
add i1 to "inserted indexes" if smaller list is before
add i1 to "deleted indexes" if smaller list is after
// Find new indexes:
for each key x in map:
add map.get(x) to "deleted indexes" if smaller list is before
add map.get(x) to "inserted indexes" if smaller list is after
我的应用程序使用SpringMVC+Hibernate+MySQL组合 我从一开始就纠结于一个问题- “在我的应用程序中,有些表使用Hibernate添加了自动递增功能.因此,当我删除任何记录时,当我再次插入一些记录时,我没有得到正确的顺序.” 为。假设我的表ABC最初有100条记录(例如,abc_id的主键具有从1到100的正确顺序的值)。 当我删除。50个记录,再插入50个记录,但这个时间序列
问题内容: 我生成一个SQLite表(在Java中): 之后,我尝试使用INSERT命令添加行: 我得到错误: 我以为行ID会自动生成,但似乎我什么都没想。 我尝试了另一种解决方案: 结果,我在“ prep.setInt(1,n);”处收到一个空指针异常。 看到故障了吗? 问题答案: 您是否尝试指出要传递的参数应该与表的哪些字段相关? 在您的情况下,可能类似于:
在Liquibase留档中,我可以看到的ChangeSet操作...然而,与之相反的(?)似乎不存在。 在数据库表中,我已从单字段自动增量id()切换为复合id(超过3列)。在3列上添加新的主索引(、、)似乎工作正常。 在新设计下,我的应用程序可以显式设置WidgetId(例如:1、2、3…等) 但是,当我的应用程序将新数据插入表时,我收到以下错误: 当我查看表时,的类型是-这是以前数据库设计的遗
问题内容: 我正在寻找这样的查询: id | int | 自动增量 varchar | 255 这样桌子就看起来像 1 | val1 2 | val2 3 | val3 … 除了id总是以每一行都结束而已。 我怎样才能做到这一点? 问题答案:
问题内容: 如何在Java中计算两个角度量度(以度为单位)的差,使结果在[0°,180°]范围内? 例如: 问题答案: /* * Shortest distance (angular) between two angles. * It will be in range [0, 180]. / public static int distance(int alpha, int beta) { int
问题内容: 使用Postgres,我试图用SQL自动编号主键。但是,这给了我一个错误。 错误: 知道为什么吗? 问题答案: Postgres 10或更高版本 列(请参见下文)保持不变。但是考虑一个 专栏。Postgres10实现了此标准SQL功能。 手册中的基本语法和信息。 __用列 创建 表 将 列 添加 到现有表 表可能填充也可能不填充行。 同时使它成为PK(表还不能拥有PK): 有关的: 如