在python中跳转搜索算法

时间:2017-10-25 11:34:55

标签: python algorithm

我正在尝试在python中实现跳转搜索。

这是代码

'''
2 jump search
'''
import math
def jump_search(arr,search):
    interval = int(math.sqrt(len(arr)))
    for i in range(0,len(arr),interval):
        if arr[i] >  search:
            chunk = i
            break
        if arr[i] ==  search:
            return i
    arr_ls = arr[chunk-interval:chunk]
    ind = [i for i,d in enumerate(arr_ls) if d==search]
    return chunk-interval+ind[0]
arr = [ i for i in range(1,200,15)]

res = jump_search(arr, 121)
print(res)

这是我面临的问题:

  1. 最后一个块正在跳过
  2. 改进版本? 另外我不认为我的代码干净简短

3 个答案:

答案 0 :(得分:3)

目前,如果search变量出现在最后一个块中,则块不会被初始化。因此,你必须得到一个错误。那么为什么不专门检查最后一个间隔。我添加了一个flag变量来检查它。如果发现了块,那么好,否则我们必须看到最后一个间隔。

import math
def jump_search(arr,search):
    flag = 0
    interval = int(math.sqrt(len(arr)))
    for i in range(0,len(arr),interval):
        if arr[i] >  search:
            chunk = i
            flag = 1
            break
        if arr[i] ==  search:
            return i
    if flag==0:
        c=i
        for j in arr[i:]:
            if j==search:
                return c
            c+=1
    else:
        arr_ls = arr[chunk-interval:chunk]
        ind = [i for i,d in enumerate(arr_ls) if d==search]
        return chunk-interval+ind[0]
arr = [ i for i in range(1,200,15)]
res = jump_search(arr, 196)
print(res) 
# prints 13

此外,如果您跟踪lower bound而不是现在正在执行的upper bound,则无法完成所有这些操作。因此,为了让您更好地编写代码,请尝试以下方法:

import math
def jump_search(arr,search):
    low = 0
    interval = int(math.sqrt(len(arr)))
    for i in range(0,len(arr),interval):
        if arr[i] < search:
            low = i
        elif arr[i] == search:
            return i
        else:
            break # bigger number is found
    c=low
    for j in arr[low:]:
        if j==search:
            return c
        c+=1
    return "Not found"

arr = [ i for i in range(1,200,15)]
res = jump_search(arr, 196)
print(res)
# prints 13

答案 1 :(得分:1)

您的代码会跳过最后一个块,因为for循环的步长大于最后一个块长度。如果您尝试不在列表中的搜索元素,它也会失败。

总之 - 这应该对你有用:

import math


def jump_search(arr, search):
    interval = int(math.sqrt(len(arr)))
    i = 0
    # set i to zero if list is empty
    for i in range(0, len(arr), interval):
        if arr[i] > search:
            break
        if arr[i] == search:
            return i
    else:
        # if loop exited normaly - add interval to i, so last chuck is included too
        i += interval

    last_chunk = arr[i - interval:i]

    # iterate directly and simply break if item found
    for ind, val in enumerate(last_chunk):
        if val == search:
            break
    else:
        # if loop exited normaly - item not found in chunk
        # return None instead of index
        return None
    return i - interval + ind

答案 2 :(得分:0)

是否可以考虑(并非完全是一种改进),但可以替代上面的代码?

def jumpSearch(a,m,x):
    for i in range(0,len(a),m):
        if a[i]==x:
           return i
        elif a[i]>x:
           high = i
           break

    for j in range(high,high-m,-1):
        if a[j]==x:
           return j