【问题标题】:Comparing two lists and fetching child objects比较两个列表并获取子对象
【发布时间】:2019-11-16 02:39:17
【问题描述】:

我有 2 个列表。一个,只有父对象,另一个可能有它的子对象。

由于这些列表可能很大,我需要一种方法来仅获取子对象,方法是比较两个列表,而不是 O(n^2)

对象成为子对象的条件是它应该以其父对象名称作为其基础。例如:'abcd' 将是 'abc' 的子对象。

List<String> childList=new ArrayList<>();
for(String parent: parentList){
  for(String child: childList){
    if(child.matches(parent + "(.*)"))
      childList.add(child)
  }
}

对于大约 14k 个对象,这需要大约 10 秒。有人可以帮我优化一下吗

【问题讨论】:

  • 要么你错过了什么,要么我错过了一些东西。在您当前的代码中,什么都不会发生...childList 在初始化时为空,第二个FOR 循环将进行 0 次迭代..
  • 使用 trie 作为数据结构。
  • 对每个列表进行排序,然后按顺序遍历每个列表。
  • 子字符串到底长什么样?有没有办法查看父名的结尾?一些示例数据会非常有用。

标签: java algorithm optimization


【解决方案1】:

如果我很好地理解了您的问题,您有 2 个字符串列表,AB。目标是确定B 中的哪些字符串是A 中字符串的前缀。
然后,存在一个名为 trie 的数据结构,它正是这样做的。
首先,您需要将 A 的每个字符串插入到您的 trie 中。
那么对于B的每一个字符串,你可以做以下事情:通过读取当前字符串(或单词)来遍历trie。如果您因为缺少节点而无法走到单词的末尾,那么当前单词不是任何对象的“孩子”。
另一方面,如果您完成了当前单词并且仍在尝试中,那么您的单词是预先存储的单词的前缀。 您应该找到 java 尝试的实现(或有关如何实现它们的想法)here

【讨论】:

    【解决方案2】:

    根据您名字的长度,您可以在第一遍中创建一个包含所有子名字前缀的映射。 (花费 O(n*nameLength) 时间)

    您可以在 O(1)(如果您使用 HashMap)中查找每个父级,哪些子级以父级名称作为前缀。

    您绝对应该尽量避免使用 RegExp 进行匹配。这些都不便宜!


    附: 如果只是检测前缀,您也可以在 Google 上搜索“前缀树”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多