Skip to content
Related Articles

Related Articles

Count palindromic characteristics of a String
  • Difficulty Level : Expert
  • Last Updated : 03 Aug, 2018

Given a string s of length n, count the number of substrings having different types of palindromic characteristics.
Palindromic Characteristic is the number of k-palindromes in a string where k lies in range [0, n).
A string is 1-palindrome(or simply palindrome) if and only if it reads same the backward as it reads forward.
A string is k-palindrome (k > 1) if and only if :
1. Its left half is equal to its right half.
2. Its left half and right half should be non-empty (k – 1)-palindrome. The left half of a string of length ‘t’ is its prefix of length ⌊t/2⌋, and right half is the suffix of the same length.
Note : Each substring is counted as many times as it appears in the string. For example, in the string “aaa” the substring “a” appears 3 times.

Examples :

Input : abba
Output : 6 1 0 0
Explanation : 
"6" 1-palindromes = "a", "b", "b", "a", "bb", "abba".
"1" 2-palindrome = "bb". Because "b" is 1-palindrome 
and "bb" has both left and right parts equal. 
"0" 3-palindrome and 4-palindrome.

Input : abacaba
Output : 12 4 1 0 0 0 0
Explanation : 
"12" 1-palindromes = "a", "b", "a", "c", "a", "b", 
"a", "aba", "aca", "aba", "bacab", "abacaba".
"4" 2-palindromes = "aba", "aca", "aba", "abacaba". 
Because "a" and "aba" are 1-palindromes.
NOTE :  "bacab" is not 2-palindrome as "ba" 
is not 1-palindrome. "1" 3-palindrome = "abacaba". 
Because is "aba" is 2-palindrome. "0" other 
k-pallindromes where 4 < = k < = 7.

Approach : Take a string s and say it is a 1-palindrome and checking its left half also turns out to be a 1-palindrome then, obviously its right part will always be equal to left part (as the string is also a 1-palindrome) making the original string to be 2-palindrome. Now, similarly, checking the left half of the string, it also turns out to be a 1-palindrome then it will make left half to be 2-palindrome and hence, making original string to be 3-palindrome and so on checking it till only 1 alphabet is left or the part is not a 1-palindrome.
Lets take string = “abacaba”. As known “abacaba” is 1-palindrome. So, when checking for its left half “aba”, which is also a 1-palindrome, it makes “abacaba” a 2-palindrome. Then, check for “aba”‘s left half “a” which is also a 1-palindrome. So it makes “aba” a 2-palindrome and “aba” makes “abacaba” a 3-palindrome. So in other words, if a string is a k-palindrome then it is also a (k-1)-palindrome, (k-2)-palindrome and so on till 1-palindrome. Code for the same is given below which firsts check each and every substring if it is a palindrome or not and then counts the number of k-palindromic substrings recursively in logarithmic time.

Below is the implementation of above approach :

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A C++ program which counts different
// palindromic characteristics of a string.
#include <bits/stdc++.h>
using namespace std;
  
const int MAX_STR_LEN = 1000;
  
bool P[MAX_STR_LEN][MAX_STR_LEN];
int Kpal[MAX_STR_LEN];
  
// A C++ function which checks whether a
// substring str[i..j] of a given string
// is a palindrome or not.
void checkSubStrPal(string str, int n)
{
  
    // P[i][j] = true if substring str
    // [i..j] is palindrome, else false
    memset(P, false, sizeof(P));
  
    // palindrome of single length
    for (int i = 0; i < n; i++)
        P[i][i] = true;
  
    // palindrome of length 2
    for (int i = 0; i < n - 1; i++)
        if (str[i] == str[i + 1])
            P[i][i + 1] = true;
  
    // Palindromes of length more then 2.
    // This loop is similar to Matrix Chain
    // Multiplication. We start with a gap of
    // length 2 and fill P table in a way that
    // gap between starting and ending indexes
    // increases one by one by outer loop.
    for (int gap = 2; gap < n; gap++)
    {
  
        // Pick starting point for current gap
        for (int i = 0; i < n - gap; i++)
        {
  
            // Set ending point
            int j = gap + i;
  
            // If current string is palindrome
            if (str[i] == str[j] && P[i + 1][j - 1])
                P[i][j] = true;
        }
    }
}
  
// A C++ function which recursively
// counts if a string str [i..j] is
// a k-palindromic string or not.
void countKPalindromes(int i, int j, int k)
{
    // terminating condition for a
    // string which is a k-palindrome.
    if (i == j)
    {
        Kpal[k]++;
        return;
    }
  
    // terminating condition for a
    // string which is not a k-palindrome.
    if (P[i][j] == false)
        return;
  
    // increases the counter for the
    // string if it is a k-palindrome.
    Kpal[k]++;
  
    // mid is middle pointer of
    // the string str [i...j].
    int mid = (i + j) / 2;
  
    // if length of string which is
    // (j - i + 1) is odd than we have
    // to subtract one from mid.
    // else if even then no change.
    if ((j - i + 1) % 2 == 1)
        mid--;
  
    // if the string is k-palindrome
    // then we check if it is a
    // (k+1) - palindrome or not by
    // just sending any of one half of
    // the string to the Count_k_Palindrome
    // function.
    countKPalindromes(i, mid, k + 1);
}
  
void printKPalindromes(string s)
{
  
    // Count of k-palindromes is equal
    // to zero initially.
    memset(Kpal, 0, sizeof(Kpal));
  
    // Finding all palindromic
    // substrings of given string
    int n = s.length();
    checkSubStrPal(s, n);
  
    // counting k-palindromes for each and
    // every substring of given string. .
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n - i; j++)
            countKPalindromes(j, j + i, 1);
  
    // Output the number of K-palindromic
    // substrings of a given string.
    for (int i = 1; i <= n; i++)
        cout << Kpal[i] << " ";
    cout << "\n";
}
  
// Driver code
int main()
{
    string s = "abacaba";
    printKPalindromes(s);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program which counts 
// different palindromic 
// characteristics of a string.         
import java.io.*;
  
class GFG
{
    static int MAX_STR_LEN = 1000;
      
    static boolean P[][] = 
           new boolean[MAX_STR_LEN][MAX_STR_LEN];
    static int []Kpal = 
           new int[MAX_STR_LEN];
      
    // function which checks 
    // whether a substring 
    // str[i..j] of a given 
    // string is a palindrome or not.
    static void checkSubStrPal(String str, 
                               int n)
    {
      
        // P[i,j] = true if substring 
        // str [i..j] is palindrome, 
        // else false
        for (int i = 0; i < MAX_STR_LEN; i++) 
        {
            for (int j = 0; j < MAX_STR_LEN; j++)
                P[i][j] = false;
            Kpal[i] = 0;
        }
          
        // palindrome of 
        // single length
        for (int i = 0; i < n; i++)
            P[i][i] = true;
      
        // palindrome of 
        // length 2
        for (int i = 0; i < n - 1; i++)
            if (str.charAt(i) == str.charAt(i + 1))
                P[i][i + 1] = true;
      
        // Palindromes of length 
        // more then 2. This loop 
        // is similar to Matrix 
        // Chain Multiplication. 
        // We start with a gap of 
        // length 2 and fill P table 
        // in a way that gap between 
        // starting and ending indexes
        // increases one by one by 
        // outer loop.
        for (int gap = 2; gap < n; gap++)
        {
      
            // Pick starting point
            // for current gap
            for (int i = 0; i < n - gap; i++)
            {
      
                // Set ending point
                int j = gap + i;
      
                // If current string
                // is palindrome
                if (str.charAt(i) == str.charAt(j) && 
                                     P[i + 1][j - 1])
                    P[i][j] = true;
            }
        }
    }
      
    // A function which recursively
    // counts if a string str [i..j] is
    // a k-palindromic string or not.
    static void countKPalindromes(int i, int j, 
                                  int k)
    {
        // terminating condition 
        // for a string which is
        // a k-palindrome.
        if (i == j)
        {
            Kpal[k]++;
            return;
        }
      
        // terminating condition for 
        // a string which is not a 
        // k-palindrome.
        if (P[i][j] == false)
            return;
      
        // increases the counter 
        // for the string if it 
        // is a k-palindrome.
        Kpal[k]++;
      
        // mid is middle pointer of
        // the string str [i...j].
        int mid = (i + j) / 2;
      
        // if length of string which 
        // is (j - i + 1) is odd than
        // we have to subtract one 
        // from mid else if even then 
        // no change.
        if ((j - i + 1) % 2 == 1)
            mid--;
      
        // if the string is k-palindrome
        // then we check if it is a
        // (k+1) - palindrome or not 
        // by just sending any of one 
        // half of the string to the 
        // Count_k_Palindrome function.
        countKPalindromes(i, mid, k + 1);
    }
      
    static void printKPalindromes(String s)
    {
        // Finding all palindromic
        // substrings of given string
        int n = s.length();
        checkSubStrPal(s, n);
      
        // counting k-palindromes for 
        // each and every substring 
        // of given string. .
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n - i; j++)
                countKPalindromes(j, j + i, 1);
      
        // Output the number of 
        // K-palindromic substrings
        // of a given string.
        for (int i = 1; i <= n; i++)
            System.out.print(Kpal[i] + " ");
        System.out.println();
    }
      
    // Driver code
    public static void main(String args[])
    {
        String s = "abacaba";
        printKPalindromes(s);
    }
}
  
// This code is contributd by
// Manish Shaw(manishshaw1)

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program which counts 
# different palindromic 
# characteristics of a string.         
MAX_STR_LEN = 1000;
  
P = [[0 for x in range(MAX_STR_LEN)] 
        for y in range(MAX_STR_LEN)] ;
  
for i in range(0, MAX_STR_LEN) :
    for j in range(0, MAX_STR_LEN) :
        P[i][j] = False;
          
Kpal = [0] * MAX_STR_LEN;
      
# def which checks
# whether a substr[i..j] 
# of a given is a 
# palindrome or not.
def checkSubStrPal(str, n) :
  
    global P, Kpal, MAX_STR_LEN;
              
    # P[i,j] = True if substr
    # [i..j] is palindrome,
    # else False
    for i in range(0, MAX_STR_LEN) :
  
        for j in range(0, MAX_STR_LEN) :
            P[i][j] = False;
        Kpal[i] = 0;
      
    # palindrome of 
    # single length
    for i in range(0, n) :
        P[i][i] = True;
  
    # palindrome of
    # length 2
    for i in range(0, n - 1) :
        if (str[i] == str[i + 1]) :
            P[i][i + 1] = True;
  
    # Palindromes of length more 
    # then 2. This loop is similar 
    # to Matrix Chain Multiplication. 
    # We start with a gap of length 
    # 2 and fill P table in a way 
    # that gap between starting and 
    # ending indexes increases one 
    # by one by outer loop.
    for gap in range(2, n) :
  
        # Pick starting point
        # for current gap
        for i in range(0, n - gap) :
  
            # Set ending point
            j = gap + i;
  
            # If current string
            # is palindrome
            if (str[i] == str[j] and 
                P[i + 1][j - 1]) :
                P[i][j] = True;
  
# A Python def which 
# recursively counts if 
# a str [i..j] is a 
# k-palindromic or not.
def countKPalindromes(i, j, k) :
  
    global Kpal, P;
      
    # terminating condition 
    # for a which is a
    # k-palindrome.
    if (i == j) :
      
        Kpal[k] = Kpal[k] + 1;
        return;
  
    # terminating condition 
    # for a which is not a 
    # k-palindrome.
    if (P[i][j] == False) :
        return;
  
    # increases the counter
    # for the if it is a 
    # k-palindrome.
    Kpal[k] = Kpal[k] + 1;
  
    # mid is middle pointer 
    # of the str [i...j].
    mid = int((i + j) / 2);
  
    # if length of which is
    # (j - i + 1) is odd than 
    # we have to subtract one 
    # from mid else if even 
    # then no change.
    if ((j - i + 1) % 2 == 1) :
        mid = mid - 1;
  
    # if the is k-palindrome
    # then we check if it is a
    # (k+1) - palindrome or not 
    # by just sending any of 
    # one half of the to the 
    # Count_k_Palindrome def.
    countKPalindromes(i, mid, k + 1);
  
def printKPalindromes(s) :
  
    global P, Kpal, MAX_STR_LEN;
              
    # Finding all palindromic
    # substrings of given string
    n = len(s);
    checkSubStrPal(s, n);
  
    # counting k-palindromes 
    # for each and every sub 
    # of given string. .
    for i in range(0, n) :
        for j in range(0, n - i) :
            countKPalindromes(j, j + i, 1);
  
    # Output the number of 
    # K-palindromic substrings
    # of a given string.
    for i in range(1, n + 1) :
        print (Kpal[i], end=" ");
    print();
  
  
# Driver code
s = "abacaba";
printKPalindromes(s);
  
# This code is contributd by
# Manish Shaw(manishshaw1)

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program which counts 
// different palindromic 
// characteristics of a string.         
using System;
  
class GFG
{
    static int MAX_STR_LEN = 1000;
      
    static bool [,]P = new bool[MAX_STR_LEN, 
                                MAX_STR_LEN];
    static int []Kpal = new int[MAX_STR_LEN];
      
    // function which checks whether
    // a substring str[i..j] of a 
    // given string is a palindrome or not.
    static void checkSubStrPal(string str, 
                               int n)
    {
      
        // P[i,j] = true if substring str
        // [i..j] is palindrome, else false
        for (int i = 0; i < MAX_STR_LEN; i++) 
        {
            for (int j = 0; j < MAX_STR_LEN; j++)
                P[i, j] = false;
            Kpal[i] = 0;
        }
          
        // palindrome of single length
        for (int i = 0; i < n; i++)
            P[i, i] = true;
      
        // palindrome of length 2
        for (int i = 0; i < n - 1; i++)
            if (str[i] == str[i + 1])
                P[i, i + 1] = true;
      
        // Palindromes of length more 
        // then 2. This loop is similar 
        // to Matrix Chain Multiplication. 
        // We start with a gap of length 2 
        // and fill P table in a way that
        // gap between starting and ending 
        // indexes increases one by one by
        // outer loop.
        for (int gap = 2; gap < n; gap++)
        {
      
            // Pick starting point
            // for current gap
            for (int i = 0; i < n - gap; i++)
            {
      
                // Set ending point
                int j = gap + i;
      
                // If current string
                // is palindrome
                if (str[i] == str[j] && 
                        P[i + 1, j - 1])
                    P[i, j] = true;
            }
        }
    }
      
    // A C++ function which recursively
    // counts if a string str [i..j] is
    // a k-palindromic string or not.
    static void countKPalindromes(int i, int j, 
                                  int k)
    {
        // terminating condition for a
        // string which is a k-palindrome.
        if (i == j)
        {
            Kpal[k]++;
            return;
        }
      
        // terminating condition for 
        // a string which is not a 
        // k-palindrome.
        if (P[i, j] == false)
            return;
      
        // increases the counter for the
        // string if it is a k-palindrome.
        Kpal[k]++;
      
        // mid is middle pointer of
        // the string str [i...j].
        int mid = (i + j) / 2;
      
        // if length of string which is
        // (j - i + 1) is odd than we have
        // to subtract one from mid.
        // else if even then no change.
        if ((j - i + 1) % 2 == 1)
            mid--;
      
        // if the string is k-palindrome
        // then we check if it is a
        // (k+1) - palindrome or not 
        // by just sending any of one 
        // half of the string to the 
        // Count_k_Palindrome function.
        countKPalindromes(i, mid, k + 1);
    }
      
    static void printKPalindromes(string s)
    {
        // Finding all palindromic
        // substrings of given string
        int n = s.Length;
        checkSubStrPal(s, n);
      
        // counting k-palindromes for each and
        // every substring of given string. .
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n - i; j++)
                countKPalindromes(j, j + i, 1);
      
        // Output the number of K-palindromic
        // substrings of a given string.
        for (int i = 1; i <= n; i++)
            Console.Write(Kpal[i] + " ");
        Console.WriteLine();
    }
      
    // Driver code
    static void Main()
    {
        string s = "abacaba";
        printKPalindromes(s);
    }
}
  
// This code is contributd by
// Manish Shaw(manishshaw1)

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program which counts 
// different palindromic 
// characteristics of a string.         
$MAX_STR_LEN = 1000;
  
$P = array(array());
$Kpal = array_fill(0, $MAX_STR_LEN, 0);
  
for($i = 0; $i < $MAX_STR_LEN; $i++) 
{
    for($j = 0; $j < $MAX_STR_LEN; $j++)
        $P[$i][$j] = false;
}
      
// function which checks
// whether a substr[i..j] 
// of a given is a 
// palindrome or not.
function checkSubStrPal($str
                        $n)
{
    global $P, $Kpal
           $MAX_STR_LEN;
             
    // P[i,j] = true if substr
    // [i..j] is palindrome, else false
    for ($i = 0; 
         $i < $MAX_STR_LEN; $i++) 
    {
        for ($j = 0; 
             $j < $MAX_STR_LEN; $j++)
            $P[$i][$j] = false;
        $Kpal[$i] = 0;
    }
      
    // palindrome of 
    // single length
    for ($i = 0; $i < $n; $i++)
        $P[$i][$i] = true;
  
    // palindrome of
    // length 2
    for ($i = 0; $i < $n - 1; $i++)
        if ($str[$i] == $str[$i + 1])
            $P[$i][$i + 1] = true;
  
    // Palindromes of length more 
    // then 2. This loop is similar 
    // to Matrix Chain Multiplication. 
    // We start with a gap of length 
    // 2 and fill P table in a way 
    // that gap between starting and 
    // ending indexes increases one 
    // by one by outer loop.
    for ($gap = 2; $gap < $n; $gap++)
    {
        // Pick starting point
        // for current gap
        for ($i = 0; 
             $i < $n - $gap; $i++)
        
            // Set ending point
            $j = $gap + $i;
  
            // If current string
            // is palindrome
            if ($str[$i] == $str[$j] && 
                    $P[$i + 1][$j - 1])
                $P[$i][$j] = true;
        }
    }
}
  
// A PHP function which 
// recursively counts if 
// a str [i..j] is a 
// k-palindromic or not.
function countKPalindromes($i, $j, $k)
{
    global $Kpal, $P;
      
    // terminating condition for a
    // which is a k-palindrome.
    if ($i == $j)
    {
        $Kpal[$k]++;
        return;
    }
  
    // terminating condition 
    // for a which is not a 
    // k-palindrome.
    if ($P[$i][$j] == false)
        return;
  
    // increases the counter
    // for the if it is a 
    // k-palindrome.
    $Kpal[$k]++;
  
    // mid is middle pointer 
    // of the str [i...j].
    $mid = ($i + $j) / 2;
  
    // if length of which is
    // (j - i + 1) is odd than 
    // we have to subtract one 
    // from mid else if even 
    // then no change.
    if (($j - $i + 1) % 2 == 1)
        $mid--;
  
    // if the is k-palindrome
    // then we check if it is a
    // (k+1) - palindrome or not 
    // by just sending any of 
    // one half of the to the 
    // Count_k_Palindrome function.
    countKPalindromes($i, $mid,
                      $k + 1);
}
  
function printKPalindromes($s)
{
    global $P, $Kpal
           $MAX_STR_LEN;
             
    // Finding all palindromic
    // substrings of given string
    $n = strlen($s);
    checkSubStrPal($s, $n);
  
    // counting k-palindromes 
    // for each and every sub 
    // of given string. .
    for ($i = 0; $i < $n; $i++)
        for ($j = 0; $j < $n - $i; $j++)
            countKPalindromes($j, $j
                              $i, 1);
  
    // Output the number of 
    // K-palindromic substrings
    // of a given string.
    for ($i = 1; $i <= $n; $i++)
        echo ($Kpal[$i] . " ");
    echo("\n");
}
  
// Driver code
$s = "abacaba";
printKPalindromes($s);
  
// This code is contributd by
// Manish Shaw(manishshaw1)
?>

chevron_right


Output :

12 4 1 0 0 0 0

Time Complexity : O(n^2$\log{n}$)
Auxiliary Space : O(n^2)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :