-2

i am using a list and iterating from last to first element of the strings to find the longest common sub word between them. So the value for the current iteration(LC[i][j]) will depend both on the previous iteration LC[i+1][j+1] and the current matching of the element,

I am facing two issues. - the else statement LC[i][j] = 0 is forcing the element of LC[i+1][j+1] = 0, so if there is a match in the current iteration then LC[i][j] is becoming 1(because LC[i+1][j+1] has been overwritten to 0. - on removing the else statement instead of finding longest common word it is giving longest common sub sequence. please see the output for both the cases

case 1. when else is present. 
1st str: zxab enter 2nd str: yzab 
i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 
i = 2 j = 2 LC[i][j] = 1 LC[i+1][j+1] = 0 
i = 0 j = 1 LC[i][j] = 1 LC[i+1][j+1] = 0 
max len = 1



case 2. else block removed.
i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 
i = 2 j = 2 LC[i][j] = 2 LC[i+1][j+1] = 1
i = 0 j = 1 LC[i][j] = 3 LC[i+1][j+1] = 2 

max len = 3
correct answer for max_len should have been 2.



def LCW(u,v):
    m = len(u)
    n = len(v)

    LC = [[0] * (len(v) + 1)] * (len(u) + 1)  # create the table one extra due to denote the endng of the word

    max_len = 0

    for i in range(m-1,-1,-1):    # because the strng's last elemnt can be accessed by range(m) == m-1
        for j in range(n-1,-1,-1):
            if u[i] == v[j]:
                LC[i][j] = 1 + LC[i+1][j+1]

            #else: LC[i][j] = 0
            if max_len < LC[i][j]:
                max_len = LC[i][j]
    return max_len
ps3790
  • 1
  • 4
  • 1
    Can you give an example of input, output, and expected output? – hoffee Jul 13 '18 at 18:33
  • i am using a list and iterating from last to first element of the strings to find the longest common sub word between them. So the value for the current iteration(LC[i][j]) will depend both on the previous iteration LC[i+1][j+1] and the current matching of the element. – ps3790 Jul 13 '18 at 18:34
  • I am facing two issues. - the else statement LC[i][j] = 0 is forcing the element of LC[i+1][j+1] = 0, so if there is a match in the current iteration then LC[i][j] is becoming 1(because LC[i+1][j+1] has been overwritten to 0. - on removing the else statement instead of finding longest common word it is giving longest common sub sequence. please see the output for both the cases. – ps3790 Jul 13 '18 at 18:35
  • case 1. when else is present. enter 1st str: zxab enter 2nd str: yzab i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 2 j = 2 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 0 j = 1 LC[i][j] = 1 LC[i+1][j+1] = 0 max len = 1 case 2. else block removed. i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 2 j = 2 LC[i][j] = 2 LC[i+1][j+1] = 1 i = 0 j = 1 LC[i][j] = 3 LC[i+1][j+1] = 2 max len = 3 – ps3790 Jul 13 '18 at 18:36
  • was getting error due to code block when writing the explanation along with it. hence wrote in comments. – ps3790 Jul 13 '18 at 18:37
  • So you're trying to find the longest shared substring between `u` and `v`? – hoffee Jul 13 '18 at 18:39
  • You still haven't provided an example of input and expected output. Also, you included the tag "dynamic-programming", even though this problem is not an example of dynamic programming. – Joel Jul 13 '18 at 18:39
  • yes. sub word not the sub sequence – ps3790 Jul 13 '18 at 18:42
  • case 1. when else is present. enter 1st str: zxab enter 2nd str: yzab i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 2 j = 2 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 0 j = 1 LC[i][j] = 1 LC[i+1][j+1] = 0 max len = 1 case 2. else block removed. i = 3 j = 3 LC[i][j] = 1 LC[i+1][j+1] = 0 i = 2 j = 2 LC[i][j] = 2 LC[i+1][j+1] = 1 i = 0 j = 1 LC[i][j] = 3 LC[i+1][j+1] = 2 max len = 3 – ps3790 Jul 13 '18 at 18:43
  • It would be best to edit your question to make your test case more readable. – hoffee Jul 13 '18 at 18:44
  • updated the expected output – ps3790 Jul 13 '18 at 19:01

1 Answers1

0

I think you get lost in your 2 dimensional list, which is not needed. You could just use the in operator which states either a string can be found in another one. Then the only problem is to create all the sub-strings of one of your inputs.

def sliding_window(seq, width):
    """yields all substrings of `seq` of length `width`"""
    return (seq[idx:idx+width] for idx in range(len(seq)-width+1))

def lcw(seq1, seq2):
    """length of the longest common sequence shared by seq1 and seq2"""
    max_width = min(len(seq1), len(seq2))
    for width in range(max_width, 0, -1):
        if any(sub in seq1 for sub in sliding_window(seq2, width)):
            return width
    return 0

lcw('zxab', 'yzab')
>>>
2

But it very well might be that I didn't get your definition sub word, which I could not really distinguish from sub sequence.

CodeNStuff
  • 266
  • 3
  • 11