Program to find out the palindromic borders in a string in python


Suppose we are provided with a string str. A border of a string is a substring that is a proper prefix and a suffix of that string. For example, 'ab' is a border of the string 'ababab'. A border is called a palindrome border if the border string is a palindrome. Now suppose there is f(str) number of palindrome borders in the given string str. We have to find out the sum of f(str_k) for all non-empty substrings str_k of str. The sum can be large, so a modulo operation can be performed by 10^9 + 7.

So, if the input is like str = 'pqpqp', then the output will be 5 There exists 15 substrings of the string 'pqpqp'; however only 4 substrings have palindromic borders. The strings are:

pqp : f(pqp) = 1
pqpqp : f(pqpqp) = 2
qpq : f(qpq) = 1
pqp : f(pqp) = 1

The sum of these values are 1 + 2 + 1 + 1 = 5.

To solve this, we will follow these steps −

  • Define a function palindrome_calculator() . This will take input_dict
    • ans := 0
    • for each item1, item2 in the values of input_dict, do
      • ans := ans + item2 *(floor value of (item2 - 1) / 2)
    • return ans
  • Define a function str_check() . This will take string
    • t_str := string[0]
    • for each s in string, do
      • if s is not same as t_str, then
        • return False
      • return True
  • Define a function string_res() . This will take string
    • ans := 0
    • for i in range 2 to size of string + 1, do
      • ans := ans + i *(floor value of (i - 1) / 2)
      • ans := ans mod 1000000007
    • return and
  • if str_check(string) is True, then
    • return string_res(string)
  • ans := 0
  • odd_list := a new list containing a new list, a new map, and 1
  • for each s in string, do
    • if s is not present in odd_list[1], then
      • odd_list[1, s] := 0
    • odd_list[1, s] := odd_list[1, s] + 1
  • for i in range 0 to size of string, do
    • insert i at the end of odd_list[0]
  • ans := ans + palindrome_calculator(odd_list[1])
  • even_list := a new list containing a new list, a new map, and 1
  • for i in range 0 to size of string - 1, do
    • if string[i] is same as string[i + 1], then
      • insert i at the end of even_list[0]
      • tmp := string[from index i to i + 2]
      • if tmp is not present in even_list[1], then
        • even_list[1, tmp] := 0
      • even_list[1, tmp] := even_list[1, tmp] + 1
  • ans := ans + palindrome_calculator(even_list[1])
  • for val in range 3 to size of string, do
    • if val mod 2 is same as 0, then
      • wt := even_list
    • otherwise,
      • wt := odd_list
    • new_t := a new list containing a new list, a new map, and val
    • for each index in wt[0], do
      • if index - 1 >= 0 and index + val - 2 < size of string and string[index - 1] is same as string[index + val - 2], then
        • insert index - 1 at the end of new_t[0]
        • tmp := string[from index index - 1 to index - 1 + val]
        • if tmp is not present in new_t[1], then
          • new_t[1, tmp] := 0
        • new_t[1, tmp] := new_t[1, tmp] + 1
    • ans := ans + palindrome_calculator(new_t[1])
    • ans := ans mod 1000000007
    • if val mod 2 is same as 0, then
      • even_list := new_t
    • otherwise,
      • odd_list := new_t
  • return ans

Example

Let us see the following implementation to get better understanding

def palindrome_calculator(input_dict):

   ans = 0
   for item1, item2 in input_dict.items():
      ans += item2 * (item2 - 1) // 2
   return ans

def str_check(string):
   t_str = string[0]
   for s in string:
      if s != t_str:
         return False
   return True

def string_res(string):
   ans = 0
   for i in range(2, len(string) + 1):
      ans += i * (i - 1) // 2
      ans %= 1000000007
   return ans

def solve(string):
   if str_check(string):
      return string_res(string)
   ans = 0
   odd_list = [[], {}, 1]
   for s in string:
      if s not in odd_list[1]:
         odd_list[1][s] = 0
      odd_list[1][s] += 1
   for i in range(len(string)):
      odd_list[0].append(i)
   ans += palindrome_calculator(odd_list[1])
   even_list = [[], {}, 1]
   for i in range(len(string) - 1):
      if string[i] == string[i + 1]:
         even_list[0].append(i)
         tmp = string[i:i + 2]
         if tmp not in even_list[1]:
            even_list[1][tmp] = 0
         even_list[1][tmp] += 1
   ans += palindrome_calculator(even_list[1])
   for val in range(3, len(string)):
      if val % 2 == 0:
         wt = even_list
      else:
         wt = odd_list
      new_t = [[], {}, val]
      for index in wt[0]:
         if index - 1 >= 0 and index + val - 2 < len(string) and string[index - 1] == string[index + val - 2]:
            new_t[0].append(index - 1)
            tmp = string[index - 1 : index - 1 + val]
            if tmp not in new_t[1]:
               new_t[1][tmp] = 0
            new_t[1][tmp] += 1
      ans += palindrome_calculator(new_t[1])
      ans %= 1000000007
      if val % 2 == 0:
         even_list = new_t
      else:
         odd_list = new_t
   return ans

print(solve('pqpqp'))

Input

'pqpqp'

Output

5

Updated on: 11-Oct-2021

189 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements