Print all the palindromic permutations of given string in alphabetic order in C++

C++Server Side ProgrammingProgramming

In this problem, we are given a string of size n. And we have to print all possible palindromic permutation that can be generated using the characters of the string in alphabetical order. If palindrome is not created using the string print ‘-1’.

Let’s take an example to understand the topic better −

Input:
string = “abcba”
Output :
abcba
bacba

Now, to solve this we need to find all the palindromes possible and then arrange them in alphabetical order(lexicographical order). Or another way could be finding the lexicographically first palindrome that is made from the string. Then find the sequentially next palindrome of the sequence.

For this, we will do the following steps −

Step 1 − store the frequency of occurrence of all characters of the string.

Step 2 − Now check if the string can form a palindrome. If no PRINT “No palindrome can be formed ” and exit. Otherwise do −

Step 3 − Create a string based on the logic that all characters with even occurrence form a string and odd occurrence from others. And we will sandwich the odd string between even string (i.e. in the form even_string + odd_string + even_string).

Using this we can find lexicographically first palindrome. Then find the next by check concurrent lexicographical combinations.

Example

PROGRAM to illustrate the concept −

#include <iostream>
#include <string.h>
using namespace std;
const char MAX_CHAR = 26;
void countFreq(char str[], int freq[], int n){
   for (int i = 0; i < n; i++)
      freq[str[i] - 'a']++;
}
bool canMakePalindrome(int freq[], int n){
   int count_odd = 0;
   for (int i = 0; i < 26; i++)
      if (freq[i] % 2 != 0)
         count_odd++;
      if (n % 2 == 0) {
         if (count_odd > 0)
            return false;
         else
            return true;
      }
      if (count_odd != 1)
         return false;
   return true;
}
bool isPalimdrome(char str[], int n){
   int freq[26] = { 0 };
   countFreq(str, freq, n);
   if (!canMakePalindrome(freq, n))
      return false;
   char odd_char;
   for (int i = 0; i < 26; i++) {
      if (freq[i] % 2 != 0) {
         freq[i]--;
         odd_char = (char)(i + 'a');
         break;
      }
   }
   int front_index = 0, rear_index = n - 1;
   for (int i = 0; i < 26; i++) {
      if (freq[i] != 0) {
         char ch = (char)(i + 'a');
         for (int j = 1; j <= freq[i] / 2; j++) {
            str[front_index++] = ch;
            str[rear_index--] = ch;
         }
      }
   }
   if (front_index == rear_index)
      str[front_index] = odd_char;
   return true;
}
void reverse(char str[], int i, int j){
   while (i < j) {
      swap(str[i], str[j]);
      i++;
      j--;
   }
}
bool nextPalindrome(char str[], int n){
   if (n <= 3)
      return false;
   int mid = n / 2 - 1;
   int i, j;
   for (i = mid - 1; i >= 0; i--)
      if (str[i] < str[i + 1])
         break;
      if (i < 0)
         return false;
   int smallest = i + 1;
   for (j = i + 2; j <= mid; j++)
      if (str[j] > str[i] && str[j] < str[smallest])
         smallest = j;
   swap(str[i], str[smallest]);
   swap(str[n - i - 1], str[n - smallest - 1]);
   reverse(str, i + 1, mid);
   if (n % 2 == 0)
      reverse(str, mid + 1, n - i - 2);
   else
      reverse(str, mid + 2, n - i - 2);
   return true;
}
void printAllPalindromes(char str[], int n){
   if (!(isPalimdrome(str, n))) {
      cout<<"-1";
      return;
   }
   do {
      cout<<str<<endl;
   } while (nextPalindrome(str, n));
}
int main(){
   char str[] = "abccba";
   int n = strlen(str);
   cout<<”The list of palindromes possible is :\n”;
   printAllPalindromes(str, n);
   return 0;
}

Output

The list of palindromes possible is −

abccba
acbbca
baccab
bcaacb
cabbac
cbaabc
raja
Published on 17-Jan-2020 14:27:09
Advertisements