Open In App

Count palindromic characteristics of a String

Last Updated : 02 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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 the same 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 the 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-palindromes 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 the 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 the left half to be 2-palindrome and hence, making the 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. 

Let’s 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++

// 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 than 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;
}

                    

Java

// 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 than 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 contributed by
// Manish Shaw(manishshaw1)

                    

Python3

# 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
    # than 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 contributed by
# Manish Shaw(manishshaw1)

                    

C#

// 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
        // than 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 contributed by
// Manish Shaw(manishshaw1)

                    

PHP

<?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
    // than 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 contributed by
// Manish Shaw(manishshaw1)
?>

                    

Javascript

// A javascript program which counts different
// palindromic characteristics of a string.
 
let MAX_STR_LEN = 1000;
 
let P = new Array(MAX_STR_LEN);
for(let i = 0; i < MAX_STR_LEN; i++){
    P[i] = new Array(MAX_STR_LEN);
}
 
let Kpal = new Array(MAX_STR_LEN);
 
// A JavaScript function which checks whether a
// substring str[i..j] of a given string
// is a palindrome or not.
function checkSubStrPal(str, n)
{
 
    // P[i][j] = true if substring str
    // [i..j] is palindrome, else false
    for(let i = 0; i < P.length; i++){
        for(let j = 0; j < P[0].length; j++){
            P[i][j] = false;
        }
    }
 
    // palindrome of single length
    for (let i = 0; i < n; i++)
        P[i][i] = true;
 
    // palindrome of length 2
    for (let i = 0; i < n - 1; i++)
        if (str[i] == str[i + 1])
            P[i][i + 1] = true;
 
    // Palindromes of length more than 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 (let gap = 2; gap < n; gap++)
    {
 
        // Pick starting point for current gap
        for (let i = 0; i < n - gap; i++)
        {
 
            // Set ending point
            let 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.
function countKPalindromes(i, j, k)
{
    // terminating condition for a
    // string which is a k-palindrome.
    if (i == j)
    {
        Kpal[k] = Kpal[k] + 1;
        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] = Kpal[k] + 1;
 
    // mid is middle pointer of
    // the string str [i...j].
    let mid = Math.floor((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 = mid - 1;
 
    // 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);
}
 
function printKPalindromes(s)
{
 
    // Count of k-palindromes is equal
    // to zero initially.
    for(let i = 0; i < Kpal.length; i++){
        Kpal[i] = 0;
    }
 
    // Finding all palindromic
    // substrings of given string
    let n = s.length;
    checkSubStrPal(s, n);
 
    // counting k-palindromes for each and
    // every substring of given string. .
    for (let i = 0; i < n; i++)
        for (let j = 0; j < n - i; j++)
            countKPalindromes(j, j + i, 1);
 
    // Output the number of K-palindromic
    // substrings of a given string.
    for (let i = 1; i <= n; i++)
        console.log(Kpal[i] + " ");
}
 
// Driver code
let s = "abacaba";
printKPalindromes(s);

                    

Output
12 4 1 0 0 0 0 

Complexity Analysis:

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


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads