Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find out the palindromic borders in a string in python
A palindromic border is a substring that appears as both a prefix and suffix of a string, and the substring itself is a palindrome. For example, in the string 'ababab', the substring 'ab' is a border, but not palindromic. However, in 'pqpqp', the substring 'p' is both a border and palindromic.
Given a string, we need to find the sum of palindromic borders across all possible substrings. The result should be returned modulo 10^9 + 7.
Example
For the string 'pqpqp', there are 15 total substrings, but only 4 have palindromic borders ?
pqp : f(pqp) = 1 pqpqp : f(pqpqp) = 2 qpq : f(qpq) = 1 pqp : f(pqp) = 1 Sum = 1 + 2 + 1 + 1 = 5
Algorithm
The solution uses dynamic programming to identify palindromic patterns and count borders efficiently ?
def palindrome_calculator(input_dict):
"""Calculate palindromic borders from frequency dictionary"""
ans = 0
for item1, item2 in input_dict.items():
ans += item2 * (item2 - 1) // 2
return ans
def str_check(string):
"""Check if all characters in string are the same"""
t_str = string[0]
for s in string:
if s != t_str:
return False
return True
def string_res(string):
"""Special case: when all characters are same"""
ans = 0
for i in range(2, len(string) + 1):
ans += i * (i - 1) // 2
ans %= 1000000007
return ans
def solve(string):
"""Main function to find palindromic borders"""
if str_check(string):
return string_res(string)
ans = 0
MOD = 1000000007
# Handle odd-length palindromes
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])
# Handle even-length palindromes
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])
# Process longer palindromes
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 %= MOD
if val % 2 == 0:
even_list = new_t
else:
odd_list = new_t
return ans
# Test the function
result = solve('pqpqp')
print(f"Palindromic borders count: {result}")
Palindromic borders count: 5
How It Works
The algorithm processes palindromes by length, starting with single characters and pairs, then extending to longer palindromes. It uses three key components ?
- palindrome_calculator() - Counts combinations of palindromic substrings
- str_check() - Handles the special case where all characters are identical
- Dynamic expansion - Builds longer palindromes from shorter ones by checking matching boundary characters
Key Points
- A border must be both a prefix and suffix of the string
- The border itself must be a palindrome
- Results are computed modulo 10^9 + 7 to handle large numbers
- Special optimization exists when all characters in the string are identical
Conclusion
This algorithm efficiently finds palindromic borders by building palindromes incrementally and counting their occurrences as borders across all substrings. The dynamic programming approach ensures optimal time complexity for this complex string analysis problem.
---