0

This is the implementation of the Edit distance problem.

Here is the recursive version without any memoization

 def edit_distance(str_a, str_b, len_a, len_b):
    # bot strs consumed
    if len_a == 0 and len_b == 0:
       return 0

    if len_a == 0:
       return len_b

    if len_b == 0:
       return len_a

    i_a = len_a-1
    i_b = len_b-1

    if str_a[i_a] == str_b[i_b]:
       return edit_distance(str_a, str_b, i_a, i_b)

    replace = edit_distance(str_a, str_b, i_a, i_b)
    delete = edit_distance(str_a, str_b, i_a, len_b)
    insert = edit_distance(str_a, str_b, len_a, i_b)

    return 1+min(replace, delete, insert)

Now here is the memoized version where I cache the results of call.

def edit_distance_memo(str_a, str_b, len_a, len_b, cache):
  if cache[len_a][len_b] != -1:
    return cache[len_a][len_b]


  if len_a == 0 and len_b == 0:
    cache[len_a][len_b] = 0
    return 0

  if len_a == 0:
    cache[len_a][len_b] = len_b
    return len_b

  if len_b == 0:
    cache[len_a][len_b] = len_a
    return len_a

  if cache[len_a][len_b] != -1:
    return cache[len_a][len_b]

  i_a = len_a-1
  i_b = len_b-1

 if str_a[i_a] == str_b[i_b]:
   cache[len_a][len_b] =  edit_distance_memo(str_a, str_b, i_a, i_b, cache)
   return cache[len_a][len_b]

 replace = edit_distance_memo(str_a, str_b, i_a, i_b, cache)
 delete = edit_distance_memo(str_a, str_b, i_a, len_b, cache)
 insert = edit_distance_memo(str_a, str_b, len_a, i_b, cache)

 best_option = min(replace, delete, insert)

 cache[len_a][len_b] = 1 + best_option

 return cache[len_a][len_b]

Here is the calling code:

 from time import time
 str1 = "Shakespeare"
 str2 = "shake spear"
 s1 =  time()
 print edit_distance(str1, str2, len(str1), len(str2)), "edit_distance"
 print "diff---", time()-s1

 rows = len("Shakespeare")+1
 columns = len("shake spear")+1

 cache = [[-1] * columns] * rows
 st  = time()
 print edit_distance_memo("Shakespeare", "shake spear",len("Shakespeare"), len("shake spear"), cache)

For some reason the memoized version, seems to be giving a wrong answer (7 instead of 3). What is wrong here?

Thanks in advance.

Nishant
  • 20,354
  • 18
  • 69
  • 101
amrx
  • 673
  • 1
  • 9
  • 23
  • Stack Overflow's overly aggressive filters blocked the more useful version of this comment because they thought it was talking about downvotes, so I'll just say that `*` doesn't do what you think it does with nested lists. – user2357112 Jan 23 '18 at 08:45
  • @user2357112, can you please elaborate. The filters are marking it as duplicate. – amrx Jan 23 '18 at 08:52
  • @user2357112, TIL happened to me. The reference was same for each element in the list. Damn, I didn't know this till now. – amrx Jan 23 '18 at 09:05

0 Answers0