简体   繁体   中英

How do I run a binary search for words that start with a certain letter?

I am asked to binary search a list of names and if these names start with a particular letter, for example A, then I am to print that name. I can complete this task by doing much more simple code such as

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

but instead I am asked to use a binary search and I'm struggling to understand the process behind it. We are given base code which can output the position a given string. My problem is not knowing what to edit so that I can achieve the desired outcome

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.")

Desired outcome

bin_search(name_list,"A")

Prints all the names starting with A (Adolphus of HelBorne, Aldric Foxe .... etc)

EDIT: I was just doing some guess and check and found out how to do it. This is the solution code

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)

Not too sure if this is what you want as it seems inefficient... as you mention it seems a lot more intuitive to just iterate over the entire list but using binary search i found here i have:

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]

Output i get:

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

You just need to found one item starting with the letter, then you need to identify the range. This approach should be fast and memory efficient.

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.")

the output is

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM