Reputation: 499
I am trying to implement jump search in python.
here is the code
'''
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)
here is the problems I am facing :
Upvotes: 0
Views: 2948
Reputation: 2151
Can this be considered (not exactly an improvement) but as an alternate to the above code?
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
Upvotes: 0
Reputation: 4407
Presently, if the search
variable is present in the last chunk, then chunk won't be initialized. And hence, you must be getting an error. So why don't you check for the last interval specifically. I have added a flag
variable which checks for that. If chunk is found, well and good, otherwise we have to see the last interval.
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
Also, you won't have to do all this, if you keep track of the lower bound
instead of the upper bound
which you are doing now. So to make you code better, which you asked for, try this:
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
Upvotes: 3
Reputation: 1608
Your code skips last chunk, because step of for loop is greater than last chunk length. Also it would fail if you try search element which is not in list.
In summary - this should work for you:
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
Upvotes: 1