Distinct palindromic sub-strings of the given string using Dynamic Programming


Introduction

In this tutorial, we discuss an approach to finding all possible palindrome substrings using the input string. To implement the approach for this task we use C++ programming language and its functions.

A palindrome is a string that reads the same from the back and front. For example, Mom is a palindrome string. In this tutorial, we take a string and find all possible palindrome substrings from it.

Example 1

String = abcaa

Output

The possible palindromic substrings are : a, b, c, aa, aaa, aba, and aca.

In the above example, the input string can make 7 palindrome substrings: ‘a’, ‘b’, ‘c’, ‘aa’, ‘aaa’, ‘aba’, and ‘aca’.

Example 2

String = “abcd”

Output

a, b, c, and d.

In the above example, using the input string only 4 palindrome substrings can be of length 1. As there is no repeating character in the input string, so the length of none of the substrings is more than 1.

Functions Used for Example Implementation

  • size() − It is a string class function and returns the length of the string counting the number of characters in the given string. It does not take parameters.

Syntax

string_name.size();

Example

str.size();
  • begin() − This library function is defined in the STL. It gives the starting iterative value of the map container.

  • Syntax : map_name.begin(); Example : mp.begin();
  • end() − This library function is defined in the STL. It gives the map container's ending iterative value.

Syntax

map_name.end();

Example

mp.end();
  • substr() − It generates a substring using an input string. It is defined in the string.h header file. It takes two parameters (pos, len). Pos is the starting value of the substring and len is the number of characters in the substring.

Syntax

string_name.substr(pos, len);

Example

str.substr();

Algorithm

  • Consider a given string to find all its palindrome substrings.

  • Find all the palindrome substrings of the input string by iterating over the string.

  • Create two arrays for odd and even-length palindrome substrings.

  • Store the values of both arrays in a hashmap.

  • Print all the values stored in the Hashmap.

  • The number of substrings equals the length of the hashmap. Iterate through the hashmap and print out each value. Use a for loop to access each item in the map and print its associated value. Finally, the number of printed values should match the size of the hashmap.

Logic 1 Example

In this section, we implement one of the above examples using the concepts of the C++ programming language. We consider an input string in the main() function and use it to generate output.

#include <iostream>
#include <map>
using namespace std;

//user defined program to find the palindrome substrings
void palindromeSubStrings(string str){
   map<string, int> mp;
   int l = str.size();
   
   //store odd and even length palindrome substrings
   int R[2][l+1];
   
   //Using guards for effortless iteration over the input string and generating all palindrome
   // substrings
   str = "@" + str + "#";
   
   for (int i = 0; i <= 1; i++) {
      int r = 0;  
      R[i][0] = 0;

      int x = 1;
      while (x <= l){
            
         while (str[x - r - 1] == str[x + i + r])
            r++; 
           
         R[i][x] = r;
         int a = 1;
         while ((R[i][x - a] != r - a) && (a < r)){
            R[i][x + a] = min(R[i][x - a],r - a);
            a++;
         }
         r = max(r - a,0);
         x += a;
      }
   }
   //storing the substring without guards
   str = str.substr(1, l);
      
   mp[string(1, str[0])]=1;
   for (int x = 1; x <= l; x++){
      for (int y = 0; y <= 1; y++)
            for (int r = R[y][x]; r > 0; r--)
               mp[str.substr(x - r - 1, 2 * r + y)]=1;
         mp[string(1, str[x])]=1;
   }
      
   //print the palindrome substrings stored in the Hashmap
   cout << "Palindrome substrings are as listed: ";
   map<string, int>::iterator xx;
   for (xx = mp.begin(); xx!=mp.end(); ++xx)
      cout << (*xx).first << endl;
}
   
//Controlling code
int main(){
   //calling the user-defined function and passing a string as argument
   palindromeSubStrings("abcaa");
   return 0;
}

Output

Palindrome substrings are listed as:
a
aa
b
c

Logic 2 Example

We are implementing another example using a dynamic programming approach. In dynamic programming, a task is divided into subtasks and solved individually to reduce the time and complexity.

#include <iostream>
#include <vector>
using namespace std;
//User defined function to find the palindromic substring 
int find(string str){
   int a = str.size();
   //defined dpg array
      vector<vector<bool> > dpg(a, vector<bool>(a, false));
      for (int x = 0; x < a; x++) {

         dpg[x][x] = 1;
  
         if (x < a && str[x] == str[x + 1]) {
            dpg[x][x + 1] = 1;
         }
      }
   // Finding length of different substrings
   for (int l = 3; l <= a; l++) {
      for (int x = 0; x + l - 1 < a; x++){
         if (str[x] == str[x + (l - 1)]
         && dpg[x + 1][x + (l - 1) - 1]) {
            dpg[x][x + (l - 1)] = true;
         }
      }
   }
 
 
   vector<int> kmp(a, 0);
   for (int x = 0; x < a; x++) {
     
      int y = 0, m = 1;
      while (m + x < a) {
         if (str[y + x] == str[m + x]){
            dpg[m + x - y][m + x] = false;
            kmp[m++] = ++y;
         }
         else if (y > 0) {
            y = kmp[y - 1];
         }
         else {
            kmp[m++] = 0;
         }
      }
   }

   int cnt = 0;
   for (int x = 0; x < a; x++) {
      string str1;
      for (int y = x; y < a; y++) {
         str1 += str[y];
         if (dpg[x][y]) {
            //counting number of palindromic substrings formed using the string
               cnt++;
               cout << str1 << '\n';
         }
      }
   }
   cout << "Total number of palindromes are "
   << cnt << '\n';
   return 0;
}
 
//Controller
int main(){
   string str = "abaa";
   find(str);
   return 0;
}

Output

a
aba
b
aa
Total number of palindromes are 4

Conclusion

In this tutorial, we developed two approaches to find all possible palindrome substrings from the given string. We understand the task through two examples and code one using C++ programming language. We use the Hashmap and vector to store the palindrome substrings to implement the example. The use of hashmap helps in matching the key value pair and we can use many hash functions as per the need. We also used some library functions to implement the example.

Updated on: 31-Jul-2023

259 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements