【发布时间】:2021-05-02 13:24:38
【问题描述】:
对于数据压缩,我想用关于该值最后出现时间的索引替换(长)列表中的值。所以列表:
18499 10123 5678 10123 10123 3344 10123 5678 4912 18499
将被替换如下:
N18449 N10123 N5678 K1 K0 N3344 K1 K2 N4912 K4
以前未见过的新值以 N 为前缀。已知的旧值以 K 为前缀。例如,第二次出现的 10123 被替换为 K1,因为还有另一个值 ( 5678)之间。但是,为了使索引尽可能低,我希望 K-indexes 不是测量列表中的距离,而是在最后一个值和当前出现值之间看到的唯一其他值的实际数量。因此,例如,将第二次出现的 5678 替换为 K2,因为它们之间还有两个其他值(10123 和 3344),即使 10123 重复了几次。类似地,最后一个值 18499 被 K4 替换,因为在它和列表的开头(也是 18499)之间还有四个其他值。如果只测量距离,则最后一个元素是 K9。
首先,看起来压缩/索引替换可以使用 LRU 缓存来完成,stackoverflow 拥有一些非常好的参考(即在 LRU cache design 上)。不幸的是,经典的 LRU 缓存对于这个目的不是很好:当查找时,如果一个项目在最后 N 个(LRU 缓存大小)项目中,那么 O(1) 的查找速度很快,实际 的查找LRU 缓存中某项的位置是 O(n)(其中 n 是找到的元素之前的元素数)。
解压步骤同样缓慢,当 Kn 需要再次替换为相应的值时:遍历经典 LRU 缓存的链表以查找要替换的项目,需要 n 步。
我很清楚,对于我的问题不存在 O(1) 解决方案,因为每次将新元素添加到缓存或一个现有的被移到前面。但是有 O(log(n)) 解决方案吗?如果可能的话,我不想使用 O(N)。
我想在 C++ 中实现它,但在任何其他编程语言中指向这种数据结构的指针也将不胜感激。我在这里询问的更多是算法而不是具体的实现。
【问题讨论】:
标签: c++ algorithm caching compression lru