【问题标题】:Using interpolation search to find beginning of list in large text file - Python使用插值搜索在大文本文件中查找列表的开头 - Python
【发布时间】:2018-01-24 23:31:13
【问题描述】:

在到达带有时间戳的行之前,我需要在行数未知的非常大的日志文件中找到最后一个时间戳。我一次将文件向后读取一行,除了一种情况外,这通常非常快。有时,我会遇到一个非常大的块(数千行),具有已知的重复模式(如下所示的一个条目)并且没有时间戳:

  goal_tolerance[0]: 
    name: joint_b
    position: -1
    velocity: -1
    acceleration: -1

由于这是我遇到此类问题的唯一情况,我可以在逐行搜索日志之前将一段代码放入检查它的循环中。

goal_tolerance 之后的数字是一个计数器,每次模式重复时都会增加 1,所以我想做的是使用该数字来计算模式的开头。我现在的样子是这样的:

if '  goal_tolerance' in line:
    gtolnum = line[17:-3]
    print gtolnum
    startFrom = currentPosition - ((long(gtolnum) + 1) * 95)
    break

但是,这并没有考虑到计数器中的字符数,所以我最终在搜索循环中运行了几次而不是必要的。有没有一种快速的方法可以将这些字符包含在计算中?

编辑:我没有阅读整个文件来达到这一点,因为它很大而且我有数百个时间戳要在数百个日志文件中搜索。我的搜索功能在文本文件中寻找一个位置,然后在该点附近找到一行的开头并读取它。计算是根据模式中的字节数或字符数确定我可以与 .seek() 一起使用的文件位置。

【问题讨论】:

  • 不够清楚,无法提供帮助:“95”从何而来?如果向后读,那找那个模式有什么意义,其余的都已经读完了。
  • 在编辑中澄清。 95 是模式每次迭代中的字符数。但是,该模式重复了几十万次,因此由于计数器的原因,字符数增加到了 100 个。
  • 与其用解决方案编辑自己的问题,不如将其添加为下面的答案,并将其标记为已接受。

标签: python search interpolation large-files


【解决方案1】:

在此期间我做了一些数学运算并想出了一个数学解决方案:

...
n = long(gtolnum)
q = len(gtolnum)        # I'll refer to this as the number's "level"
x = n + 1 - 10**(q - 1) # Number of entries in the current level
c = x * (q - 1)         # Additional digits in the current level
i = 2
p = 0
while i < q:
    p += 9 * (q - i) * (10**(q - i))  # Additional digits in i levels previous
    i += 1
startFrom = currentPosition - ((n + 1) * 95 + p + c)
...

似乎应该有一个更简单的解决方案,但我没有看到它。也许日志功能可以提供帮助?

【讨论】:

    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多