【问题标题】:Binary search to find last element in sorted list that is less then specific value二进制搜索以查找排序列表中小于特定值的最后一个元素
【发布时间】:2015-05-10 01:23:24
【问题描述】:

我正在搜索包含 unixtimes、长度为 N 的消息字典,我想在其中找到任意 24 小时(86400 秒)时隙内的最大消息数(我称之为频率)。这意味着如果在 24 小时内有 5 条带有 unixtime 的消息,我想要 5 条。

我想通过二分搜索来实现这一点,但对于如何最好地实现这一点以及是否可以使用一些二分搜索库,我有点迷茫。

这就是我使用 10 个元素的搜索网格的方法:

        cur.execute('SELECT unixtime FROM MessageType1 WHERE userID ='+str(userID[index])+' ORDER BY unixtime asc')
        AISmessages = cur.fetchall()
        AISmessages = {index:x[0] for index,x in enumerate(AISmessages)}
for nextMessageIndex in range(messageIndex+1, len(AISmessages),10):
    if  AISmessages[nextMessageIndex] < message+(86400):
    #Count the number of occurences
        frequency += 10
    elif AISmessages[nextMessageIndex-5] < message+(86400):
        if AISmessages[nextMessageIndex-2] < message+(86400):
            if AISmessages[nextMessageIndex-1] < message+(86400):
                frequency += 9
            else:
                frequency += 8
        elif AISmessages[nextMessageIndex-3] < message+(86400):
            frequency += 7
        elif AISmessages[nextMessageIndex-4] < message+(86400):
            frequency += 6
        else:
            frequency += 5
    elif AISmessages[nextMessageIndex-7] < message+(86400):
        if AISmessages[nextMessageIndex-6] < mssage+(86400):
            frequency += 4
        else:
            frequency += 3
    elif AISmessages[nextMessageIndex-9] < message+(86400):
        if AISmessages[nextMessageIndex-8]< message+(86400):
            frequency += 2
        else:
            frequency += 1
    else:
        break

我想我也搞砸了这个,但我不知道是怎么回事 - 我知道 AISmessages 的长度不能被 10 f.ex 整除是不好的

我如何将其标准化为二进制搜索,它可以在包含任意数量元素的字典中给出 24 小时时间段内消息的频率?

【问题讨论】:

    标签: python binary-search


    【解决方案1】:

    您可以使用标准库中的bisect。我不确定我是否正确理解了您的问题,但解决方案可能如下所示:

    frequency = bisect(AISmessages[messageIndex:], message+86400)
    

    示例:这为您提供列表 a 中值范围为 30 的项目数,从索引为 2 的条目开始(假设 a 已排序):

    >>> a = [4, 17, 31, 39, 41, 80, 82, 85, 86, 96]
    >>> i = 2
    >>> m = a[i] # 31
    >>> bisect(a[i:], m+30)
    3 # correct: 31, 39, 41
    

    【讨论】:

    • 我想你完全理解我的意思!谢谢!当我运行你的代码时,我得到TypeError: unhashable type,这可能是因为 AISmessages 是这样初始化的:cur.execute('SELECT messages')AISmessages = cur.fetchall()AISmessages = {index:x[0] for index,x in enumerate(AISmessages)}?抱歉没有提及
    • 您应该简单地使用列表而不是字典,因为键是数字 0、1 等。只需初始化为AISmessages = [x[0] for x in cur.fetchall()],然后我的代码就可以工作了。
    • 确实如此 - 现在我的代码运行得更快了。非常感谢!
    猜你喜欢
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多