Syntax error Program to count number of similar substrings for each query in Python

Program to count number of similar substrings for each query in Python



Suppose we have two strings s and a set of query Q. Where Q[i] contains pair (l, r), for each substring of s from l to r, we have to find number of substrings s from x to y where they are similar. Two strings s and t are similar if they follow these rules −

  • They are of same length

  • For each pair of indices (i, j), if s[i] is same as s[j], then it must satisfy t[i] = t[j], and similarly if s[i] is not same as s[j], then t[i] and t[j] must be different.

So, if the input is like s = "hjhhbcbk" Q = [(1,2), (2,4)], then the output will be [6, 1] because

  • For first query the similar substrings are "hj", "jh", "hb", "bc", "cb" and "bk".
  • For first query the similar substring is "jhh"

To solve this, we will follow these steps −

  • fp := a new list
  • Define a function calc_fingerprint() . This will take s
  • dict := a new dictionary, and initially insert key-value pair (s[0], 0)
  • fp := "0"
  • j := 1
  • for i in range 1 to size of s - 1, do
    • if s[i] is not present in dict, then
      • dict[s[i]] := j
      • j = j+1
    • fp := fp + string representation of dict[s[i]]
  • return integer form of fp
  • From the main method, do the following −
  • if size of s > 10, then
    • for i in range 0 to size of s - 10, do
      • x := calc_fingerprint(s[from index i to i+9])
      • insert x at the end of fp
  • ret := a new list
  • for i in range 0 to size of Q - 1, do
    • (a, b) := Q[i]
    • s1 := substring of s from index a-1 to b-1
    • k := 0
    • for i in range 0 to size of s - (b-a), do
      • if b-a > 9 and fp[a-1] is not same as fp[i], then
        • go for next iteration
      • dict := a new empty map
      • s2 := substring of s from index i to i+(b-a)
      • for i in range 0 to b-a, do
        • if s2[i] is not in dict, then
          • if s1[i] is in values of dict, then
            • come out from loop
          • dict[s2[i]] := s1[i]
        • if dict[s2[i]] is not same as s1[i], then
          • come out from loop
      • otherwise,
        • k := k + 1
    • insert k at the end of ret
  • return ret

Example

Let us see the following implementation to get better understanding −

fp = []

def calc_fingerprint(s):
   dict = {s[0]: 0}
   fp = "0"
   j = 1
   for i in range(1, len(s)):
      if s[i] not in dict:
         dict[s[i]], j = j, j+1
      fp += str(dict[s[i]])
   return int(fp)

def solve(s, Q):
   if len(s) > 10:
      for i in range(0, len(s)-10):
         fp.append(calc_fingerprint(s[i: i+10]))

   ret = []
   for i in range(len(Q)):
      a, b = Q[i]
      s1 = s[a-1:b]
      k = 0
      for i in range(len(s)-(b-a)):
         if b-a > 9 and fp[a-1] != fp[i]:
            continue
         dict = {}
         s2 = s[i:i+(b-a)+1]
         for i in range(b-a+1):
            if s2[i] not in dict:
               if s1[i] in dict.values(): break
               dict[s2[i]] = s1[i]
            if dict[s2[i]] != s1[i]: break
         else:
            k += 1
      ret.append(k)

   return ret

s = "hjhhbcbk"
Q = [(1,2), (2,4)]
print(solve(s, Q))

Input

"hjhhbcbk", [(1,2), (2,4)]

Output

[6, 1]
Updated on: 2021-10-11T06:15:35+05:30

369 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements