找到重要的"排序日志中的条目

时间:2017-01-29 23:47:39

标签: algorithm big-o

我有一个由几千个整数组成的日志文件,每个整数分隔成一个新行。我已将此解析为一组此类整数,也已排序。现在我的问题变成找到重要的"此日志中的整数 - 这些是显示一些用户可配置时间的部分。

例如,给定日志,用户可以过滤以仅查看显示特定次数的条目。

目前我正在扫描整个阵列并记录每个条目出现的次数。当然有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您的排序可能需要O(NlogN)时间。您是否需要为同一数据集多次(n / I)查询?

如果是,请浏览已排序的数组,生成(Value;Count)对并按Count字段对其进行排序。现在,您可以使用二进制搜索轻松地将具有高计数的对分开

答案 1 :(得分:0)

首先,我需要注意以下只是理论上的解决方案,您可能应该使用@MBo提出的建议。

获取已排序数组的每个m = n / l元素。只有那些元素才是重要的,因为mi*m之间没有长度为(i+1)*m的相同元素序列。

对于每个元素x,使用二进制搜索查找数组的下限和上限。减去索引,您可以知道计数,并决定保留或放弃x不重要。

总复杂度为O((n/m) * log n) = O(l * log n)。对于大m,它可以(渐近地)优于O(n)。但是,要在实践中获得改进,您需要非常具体的情况:

  • 数组是给你预分类的(否则只是使用计数排序,你会立即得到答案)

  • 您可以在i 中访问数组中的O(1)元素而无需读取整个数组。否则,再次使用哈希表进行计数排序。

让我们假设你有一个由排序的固定宽度整数 "data.bin"组成的文件(它也可以用于变宽,但需要额外的努力)。然后在伪代码中,算法可能是这样的:

def find_all_important(l, n):
  m = n / l
  for i = m to l step m:
    x = read_integer_at_offset("data.bin", i)
    lower_bound = find_lower_bound(x, 0, i)
    upper_bound = find_upper_bound(x, i, n)
    if upper_bound - lower_bound >= m:
      report(x)

def find_lower_bound(x, begin, end):
  if end - begin == 0:
    return begin
  mid = (end + begin) / 2
  x = read_integer_at_offset("data.bin", mid)
  if mid < x:
    return find_lower_bound(x, mid + 1, end)
  else:
    return find_lower_bound(x, begin, mid)

作为猜测,与现代硬件上的天真O(n)相比,你不会获得任何显着的改进,除非你的文件非常大(数百MB)。当然,如果您的数据不适合RAM,那么它是可行的。但是,与优化一样,它可能值得测试。