【问题标题】:Search and detect overlap in a list of Objects by start and end timestamps按开始和结束时间戳搜索和检测对象列表中的重叠
【发布时间】:2019-03-01 14:46:12
【问题描述】:

我有一个列表,我想通过设备字符串属性检测列表中重叠的任务。所以,任务会是这样的:

public class Mission {
    private String id;
    private String device;
    private long startTime;
    private long endTime;
}

我收到一个列表并希望返回相同的列表,其中子任务属性设置为“重叠”,如果:

  • 同一设备在其范围内执行了另一个任务(timestampstart 到 timestampend)。

回想一下,我需要标记所有重叠的任务。当我在列表中找到它们时,标记当前的(如果匹配)和在列表中遇到的。

我想用尽可能少的成本来做这件事。非昂贵的操作。

【问题讨论】:

  • 你为什么用List<Object>而不是List<Mission>?当id 相等时,两个Mission 是否相等?列表是否按例如排序? id?如果最后两个问题的答案是“是”,那么你可以在n * log(m)中实现你想要的。
  • @Turing85 我使用 List。他们的身份永远不相等。我可以按时间戳对其进行排序(例如开始)。问题是如何在 Java 中正确实现它。
  • 很可能,您必须覆盖equals(...)(注意equals(...)hashCode(...) 之间存在合同)。
  • 现在我们知道您想要什么了。我们不知道到目前为止尝试或研究了什么。你的具体问题是什么?你在哪里卡住了?

标签: java algorithm sorting data-structures collections


【解决方案1】:

如果你有可能使用额外的内存,我可以为你提供以下算法

  1. 创建HashMap<String, TreeSet<Mission>> map,其中device 是一个键。

  2. TreeSet 必须按startTime 排序。示例new TreeSet<>(Comparator.comparingLong(Mission::getStartTime))

  3. 使用列表中的数据初始化 map。这里的主要思想是按device 对您的数据进行分组,并按startTime 对分组数据进行排序。

  4. 然后遍历您的列表并应用以下算法:

    1. 在创建的地图中查找 TreeSet:TreeSet<Mission> set = map.get(item.device)。如果它的大小等于 1,那么您可以移动到列表中的下一项,因为集合中唯一的一项与列表中的原始项具有相同的 id。
    2. 从步骤 1 中收到的集合中查找包含元素的子集,其中 startTime 低于 item.endTime。如果它的大小等于 1,那么您可以移动到列表中的下一个项目,因为子集的唯一项目与列表中的原始项目具有相同的 id。代码示例:set = set.headSet(new Mission().setStartTime(item.getEndTime()))
    3. 在第 2 步的子集中查找第一个元素,其中 endTime 比原始 item.startTime 多。我建议您以向后的顺序移动子集set.descendingIterator() 如果您找到一个并且它的 id 不等于原始项目 id,那么您可以将项目标记为重叠并移至列表的下一个项目。否则对子集的下一个元素重复步骤 3 直到结束。

【讨论】:

  • 这很好用。但是,当您可以在第 3 步中标记您正在列表中迭代的当前项目时,但您没有标记匹配的项目(找到的具有不同 id 的项目)。
  • 我刚刚用检测到的任务的 id 填充了一个 Set,然后再次遍历列表以将任务设置为重叠。
  • 正如我从问题描述中了解到的,当两个任务具有相同的设备并且它们的时间间隔(开始和结束之间的时间)重叠时,就会发生重叠。算法看起来很复杂,因为它遵循最后一个条件。如果不需要控制时间间隔,可以将HashMap<String, TreeSet<Mission>>替换为HashMap<String, Integer>,其中value是设备id的计数。如果 count > 1 则标记 Mission 与重叠
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2018-11-07
  • 1970-01-01
相关资源
最近更新 更多