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