Program to find the indexes where the substrings of a string match with another string fully or differ at one position in python



Suppose, we are provided with two strings. The first one has a length greater than the second one, and we have to check if the substrings from the first string match exactly with the second string or differ in one position. We return the indexes of the first string, where the substrings that can match with the second string start.

So, if the input is like string1 = 'tpoint', string2 = 'pi', then the output will be 1 2.

The substring from the first string that matches with the second string or differs in one position at index 1 and 2 are 'po' and 'oi'.

To solve this, we will follow these steps −

  • Define a function search() . This will take string1, string2
    • str_cat := string1 + string2
    • z_list := a new list of the size of str_cat initialized with 0
    • z_list[0] := size of str_cat
    • right := 0
    • left := 0
    • for i in range 1 to size of str_cat, do
      • if i > right, then
        • j := 0
        • while j + i < size of str_cat and str_cat[j] is same as str_cat[j+i], do
          • j := j + 1
        • z_list[i] := j
        • if j > 0, then
          • left := i
          • right := i + j - 1
      • otherwise,
        • k := i - left
        • r_len := right - i + 1
        • if z_list[k] < r_len is non-zero, then
          • z_list[i] := z_list[k]
        • otherwise,
          • m := right + 1
          • while m < size of str_cat and str_cat[m] is same as str_cat[m - i], do
            • m := m + 1
            • z_list[i] := m - i
            • left := i
            • right := m - 1
      • z_list[i] := minimum of size of string1 , z_list[i]
    • return z_list[from index size of string1 to end]
  • fwd := search(str2, str1)
  • bwrd := search(str2[from index 0 to end], str1[from index 0 to end])
  • reverse the list bwrd
  • idx := a new list
  • for i in range 0 to size of str1 - (size of str2 + 1), do
    • if fwd[i] + bwrd[i + (size of str2 - 1)] >= size of str2 -1, then
      • insert string representation of i at the end of idx
  • if size of idx is same as 0, then
    • return False
  • otherwise,
    • string representation of idx

Example

Let us see the following implementation to get better understanding −

def search(string1, string2):
   str_cat = string1 + string2
   z_list = [0] * len(str_cat)
   z_list[0] = len(str_cat)
   right = 0
   left = 0
   for i in range(1, len(str_cat)):
      if i > right:
         j = 0
         while j + i < len(str_cat) and str_cat[j] == str_cat[j+i]:
            j += 1
         z_list[i] = j
         if j > 0:
            left = i
            right = i + j - 1
      else:
         k = i - left
         r_len = right - i + 1
         if z_list[k] < r_len:
            z_list[i] = z_list[k]
         else:
            m = right + 1
            while m < len(str_cat) and str_cat[m] == str_cat[m -i]:
               m += 1
            z_list[i] = m - i
            left = i
            right = m - 1
      z_list[i] = min(len(string1), z_list[i])
   return z_list[len(string1):]

def solve(str1, str2):
   fwd = search(str2, str1)
   bwrd = search(str2[::-1], str1[::-1])
   bwrd.reverse()
   idx = []
   for i in range(len(str1) - len(str2)+1):
      if fwd[i] + bwrd[i+len(str2)-1] >= len(str2)-1:
         idx.append(str(i))
   if len(idx) == 0:
      return False
   else:
      return (" ".join(idx))

print(solve('tpoint', 'pi'))

Input

'tpoint', 'pi'

Output

1 2

Advertisements