如何对以某个字母开头的单词运行二进制搜索?

时间:2016-09-27 04:23:36

标签: python binary-search

我被要求二进制搜索名称列表,如果这些名称以特定字母开头,例如A,那么我将打印该名称。 我可以通过更简单的代码完成此任务,例如

for i in list:
    if i[0] == "A":
        print(i)

但我被要求使用二进制搜索,我正在努力理解它背后的过程。我们给出了可以输出给定字符串位置的基本代码。我的问题是不知道要编辑什么,以便我可以达到预期的结果

name_list = ["Adolphus of Helborne", "Aldric Foxe", "Amanita Maleficant", "Aphra the Vicious", "Arachne the Gruesome", "Astarte Hellebore", "Brutus the Gruesome", "Cain of Avernus"]


def bin_search(list, item):
    low_b = 0
    up_b = len(list) - 1
    found = False

    while low_b <= up_b and found ==  False:
        midPos = ((low_b + up_b) // 2)
        if list[midPos] < item:
            low_b = midPos + 1
        elif list[midPos] > item:
            up_b = midPos - 1
        else:
            found = True
    if found:
        print("The name is at positon " + str(midPos))
        return midPos
    else:
        print("The name was not in the list.")

期望的结果

bin_search(name_list,"A")

打印所有以A开头的名字(Adolphus of HelBorne,Aldric Foxe ....等)

编辑: 我只是做了一些猜测并检查并发现了如何做到这一点。这是解决方案代码

def bin_search(list, item):
    low_b = 0
    up_b = len(list) - 1
    true_list = []
    count = 100
    while low_b <= up_b and count > 0:
        midPos = ((low_b + up_b) // 2)
        if list[midPos][0] == item:
            true_list.append(list[midPos])
            list.remove(list[midPos])
            count -= 1
        elif list[midPos] < item:
            low_b = midPos + 1
            count -= 1
        else:
            up_b = midPos - 1
            count -= 1
    print(true_list)

2 个答案:

答案 0 :(得分:0)

不太确定这是否是您想要的,因为它似乎效率低......正如您所提到的那样,只是迭代整个列表似乎更直观但使用二进制搜索我发现here我有:< / p>

def binary_search(seq, t):
    min = 0
    max = len(seq) - 1
    while True:
        if max < min:
            return -1
        m = (min + max) // 2
        if seq[m][0] < t:
            min = m + 1
        elif seq[m][0] > t:
            max = m - 1
        else:
            return m

index=0
while True:
    index=binary_search(name_list,"A")
    if index!=-1:
        print(name_list[index])
    else:
        break
    del name_list[index]

输出我得到:

Aphra the Vicious
Arachne the Gruesome
Amanita Maleficant
Astarte Hellebore
Aldric Foxe
Adolphus of Helborne

答案 1 :(得分:0)

您只需要找到一个以字母开头的项目,然后您需要确定范围。这种方法应该快速且内存效率高。

def binary_search(list,item):
    low_b = 0
    up_b = len(list) - 1
    found = False
    midPos = ((low_b + up_b) // 2)
    if list[low_b][0]==item:
        midPos=low_b
        found=True
    elif list[up_b][0]==item:
        midPos = up_b
        found=True
    while True:
        if found:
            break;
        if list[low_b][0]>item:
            break
        if list[up_b][0]<item:
            break
        if up_b<low_b:
            break;
        midPos = ((low_b + up_b) // 2)
        if list[midPos][0] < item:
            low_b = midPos + 1
        elif list[midPos] > item:
            up_b = midPos - 1
        else:
            found = True
            break
    if found:
        while True:
            if midPos>0:
                if list[midPos][0]==item:
                    midPos=midPos-1
                    continue
            break;
        while True:
            if midPos<len(list):
                if list[midPos][0]==item:
                    print list[midPos]
                    midPos=midPos+1
                    continue
            break
    else:
        print("The name was not in the list.")

输出

>>> binary_search(name_list,"A")
Adolphus of Helborne
Aldric Foxe
Amanita Maleficant
Aphra the Vicious
Arachne the Gruesome
Astarte Hellebore