Print all Palindromic Partitions of a String using Bit Manipulation (original) (raw)

Last Updated : 28 May, 2024

Try it on GfG Practice redirect icon

Given a string, find all possible palindromic partitions of a given string.

Note that this problem is different from Palindrome Partitioning Problem, there the task was to find the partitioning with minimum cuts in input string. Here we need to print all possible partitions.

**Example:

**Input: nitin
**Output: n i t i n
n iti n
nitin

**Input: geeks
**Output: g e e k s
g ee k s

Please refer Print all Palindromic Partitions of a String using Backtracking for Backtracking approach for this problem.

The idea is to consider the space between two characters in the string.

**Illustration:

**Input : geeks

0100 => ["ge","eks"] (not valid)
1011 => ["g","ee","k","s"] (valid)
1111 => ["g","e","e","k","s"] (valid)
0000 => ["geeks"] (not valid)

Below is the implementation of the idea.

C++ `

#include <bits/stdc++.h> using namespace std;

class GFG { public: vector<vector > ans;

// Checks whether a Partition of string is palindrome or
// not.
bool checkPalindrome(vector<string> currPartition)
{
    for (auto s : currPartition) {
        int n = s.size();
        int i = 0, j = n - 1;
        while (i < j) {
            if (s[i] != s[j])
                return false;
            i++;
            j--;
        }
    }
    return true;
}

// Generates partition of a string according to
// bitString.
void generatePartition(string& s, string& bitString)
{
    vector<string> currPartition;
    string subString;
    subString.push_back(s[0]);
    for (int i = 0; i < bitString.size(); i++) {

        // If current character of bitString is '0' no
        // cut will be made and next character will be
        // included in the current subString
        if (bitString[i] == '0') {
            // no cut is made so next character is added
            // to substring
            subString.push_back(s[i + 1]);
        }

        // If current character of bitString is '1' then
        // a cut will be made and current subString will
        // be appended in current Partition and new
        // subString will start from next position.
        else {
            // subString is added to current Partition.
            currPartition.push_back(subString);

            subString.clear();

            // New substring is created starting from
            // next position of string s.
            subString.push_back(s[i + 1]);
        }
    }
    currPartition.push_back(subString);
    if (checkPalindrome(currPartition)) {
        ans.push_back(currPartition);
    }
}

// Recursive function to generate all the bitStrings
// which will denote the positions in which string will
// be cut.
void bitManipulation(string& s, string& bitString)
{
    // When a bitString is generated generatePartition()
    // will be called to partition the string
    // accordingly.
    if (bitString.size() == s.size() - 1) {
        generatePartition(s, bitString);
        return;
    }
    bitString.push_back('1');
    bitManipulation(s, bitString);
    bitString.pop_back();
    bitString.push_back('0');
    bitManipulation(s, bitString);
    bitString.pop_back();
}
// Return all the palindromic partition of string s.
vector<vector<string> > Partition(string s)
{
    string bitString;
    bitManipulation(s, bitString);
    return ans;
}

};

int main() { GFG ob; // Stores all the partition vector<vector > ans; string s = "geeks"; ans = ob.Partition(s); for (auto& v : ans) { for (auto& it : v) { cout << it << " "; } cout << "\n"; } return 0; }

Java

import java.util.ArrayList; import java.util.List;

class GFG { List<List> ans = new ArrayList<>();

// Checks whether a Partition of string is palindrome or not.
boolean checkPalindrome(List<String> currPartition) {
    for (String s : currPartition) {
        int n = s.length();
        int i = 0, j = n - 1;
        while (i < j) {
            if (s.charAt(i) != s.charAt(j))
                return false;
            i++;
            j--;
        }
    }
    return true;
}

// Generates partition of a string according to bitString.
void generatePartition(String s, String bitString) {
    List<String> currPartition = new ArrayList<>();
    StringBuilder subString = new StringBuilder();
    subString.append(s.charAt(0));
    for (int i = 0; i < bitString.length(); i++) {
        // If current character of bitString is '0' no cut will be made
        // and next character will be included in the current subString
        if (bitString.charAt(i) == '0') {
            // no cut is made so next character is added to substring
            subString.append(s.charAt(i + 1));
        }
        // If current character of bitString is '1' then
        // a cut will be made and current subString will
        // be appended in current Partition and new
        // subString will start from next position.
        else {
            // subString is added to current Partition.
            currPartition.add(subString.toString());

            subString.setLength(0);

            // New substring is created starting from
            // next position of string s.
            subString.append(s.charAt(i + 1));
        }
    }
    currPartition.add(subString.toString());
    if (checkPalindrome(currPartition)) {
        ans.add(currPartition);
    }
}

// Recursive function to generate all the bitStrings
// which will denote the positions in which string will
// be cut.
void bitManipulation(String s, String bitString) {
    // When a bitString is generated generatePartition()
    // will be called to partition the string
    // accordingly.
    if (bitString.length() == s.length() - 1) {
        generatePartition(s, bitString);
        return;
    }
    bitString += '1';
    bitManipulation(s, bitString);
    bitString = bitString.substring(0, bitString.length() - 1);
    bitString += '0';
    bitManipulation(s, bitString);
    bitString = bitString.substring(0, bitString.length() - 1);
}

// Return all the palindromic partition of string s.
List<List<String>> partition(String s) {
    String bitString = "";
    bitManipulation(s, bitString);
    return ans;
}

public static void main(String[] args) {
    GFG ob = new GFG();
    // Stores all the partition
    List<List<String>> ans;
    String s = "geeks";
    ans = ob.partition(s);
    for (List<String> v : ans) {
        for (String it : v) {
            System.out.print(it + " ");
        }
        System.out.println();
    }
}

}

Python

class PalindromePartition: def init(self): self.ans = []

def check_palindrome(self, curr_partition):
    for s in curr_partition:
        n = len(s)
        i, j = 0, n - 1
        while i < j:
            if s[i] != s[j]:
                return False
            i += 1
            j -= 1
    return True

def generate_partition(self, s, bit_string):
    curr_partition = []
    sub_string = s[0]
    for i in range(len(bit_string)):
        # If current character of bitString is '0', no cut will be made,
        # and the next character will be included in the current subString.
        if bit_string[i] == '0':
            # No cut is made, so the next character is added to the substring.
            sub_string += s[i + 1]
        # If the current character of bitString is '1', then a cut will be made,
        # and the current subString will be appended in the current partition,
        # and a new subString will start from the next position.
        else:
            # SubString is added to the current partition.
            curr_partition.append(sub_string)

            # New substring is created starting from the next position of the string s.
            sub_string = s[i + 1]

    curr_partition.append(sub_string)
    if self.check_palindrome(curr_partition):
        self.ans.append(curr_partition)

def bit_manipulation(self, s, bit_string):
    # When a bitString is generated, generate_partition() will be called
    # to partition the string accordingly.
    if len(bit_string) == len(s) - 1:
        self.generate_partition(s, bit_string)
        return
    bit_string += '1'
    self.bit_manipulation(s, bit_string)
    bit_string = bit_string[:-1]  # Pop the last character
    bit_string += '0'
    self.bit_manipulation(s, bit_string)

def partition(self, s):
    bit_string = ""
    self.bit_manipulation(s, bit_string)
    return self.ans

if name == "main": ob = PalindromePartition() s = "geeks" ans = ob.partition(s) for v in ans: print(" ".join(v))

C#

using System; using System.Collections.Generic;

class GFG { private List<List> ans = new List<List>(); // Checks whether a Partition of //string is palindrome or not. private bool CheckPalindrome(List currPartition) { foreach (var s in currPartition) { int n = s.Length; int i = 0, j = n - 1; while (i < j) { if (s[i] != s[j]) return false; i++; j--; } } return true; } // Generates partition of a string // according to bitString. private void GeneratePartition(string s, string bitString) { List currPartition = new List(); string subString = s[0].ToString(); for (int i = 0; i < bitString.Length; i++) { if (bitString[i] == '0') { subString += s[i + 1]; } // If current character of bitString is '1', a cut will be made, // and the current subString will be appended in the current Partition, // and a new subString will start from the next position. else { // subString is added to current Partition. currPartition.Add(subString);

            subString = "";

            // New substring is created starting from the next position of string s.
            subString += s[i + 1];
        }
    }
    currPartition.Add(subString);
    if (CheckPalindrome(currPartition))
    {
        ans.Add(currPartition);
    }
}
// Recursive function to generate all the bitStrings
// which will denote the positions in which string will be cut.
private void BitManipulation(string s, string bitString)
{
    if (bitString.Length == s.Length - 1)
    {
        GeneratePartition(s, bitString);
        return;
    }
    bitString += '1';
    BitManipulation(s, bitString);
    bitString = bitString.Remove(bitString.Length - 1);
    bitString += '0';
    BitManipulation(s, bitString);
    bitString = bitString.Remove(bitString.Length - 1);
}
// Return all the palindromic 

// partitions of string s. public List<List> Partition(string s) { string bitString = ""; BitManipulation(s, bitString); return ans; } } class Geek { static void Main() { GFG ob = new GFG(); // Stores all the partitions List<List> ans; string s = "geeks"; ans = ob.Partition(s); foreach (var v in ans) { foreach (var it in v) { Console.Write(it + " "); } Console.WriteLine(); } } }

JavaScript

class GFG { constructor() { this.ans = []; }

// Checks whether a Partition of string is palindrome or not.
checkPalindrome(currPartition) {
    for (const s of currPartition) {
        const n = s.length;
        let i = 0, j = n - 1;
        while (i < j) {
            if (s.charAt(i) !== s.charAt(j))
                return false;
            i++;
            j--;
        }
    }
    return true;
}

// Generates partition of a string according to bitString.
generatePartition(s, bitString) {
    const currPartition = [];
    let subString = s.charAt(0);
    for (let i = 0; i < bitString.length; i++) {
        // If current character of bitString is '0' no cut will be made
        // and next character will be included in the current subString
        if (bitString.charAt(i) === '0') {
            // no cut is made so next character is added to substring
            subString += s.charAt(i + 1);
        }
        // If current character of bitString is '1' then
        // a cut will be made and current subString will
        // be appended in current Partition and new
        // subString will start from next position.
        else {
            // subString is added to current Partition.
            currPartition.push(subString);

            subString = '';

            // New substring is created starting from
            // next position of string s.
            subString += s.charAt(i + 1);
        }
    }
    currPartition.push(subString);
    if (this.checkPalindrome(currPartition)) {
        this.ans.push(currPartition);
    }
}

// Recursive function to generate all the bitStrings
// which will denote the positions in which string will
// be cut.
bitManipulation(s, bitString) {
    // When a bitString is generated generatePartition()
    // will be called to partition the string
    // accordingly.
    if (bitString.length === s.length - 1) {
        this.generatePartition(s, bitString);
        return;
    }
    bitString += '1';
    this.bitManipulation(s, bitString);
    bitString = bitString.substring(0, bitString.length - 1);
    bitString += '0';
    this.bitManipulation(s, bitString);
    bitString = bitString.substring(0, bitString.length - 1);
}

// Return all the palindromic partition of string s.
partition(s) {
    let bitString = '';
    this.bitManipulation(s, bitString);
    return this.ans;
}

}

// Create an instance of the GFG class const ob = new GFG();

// Stores all the partition let ans; const s = 'geeks'; ans = ob.partition(s);

// Print the results on the same line for (const v of ans) { let line = ''; for (const it of v) { line += it + ' '; } console.log(line); }

`

**Time complexity: O(n*2n), n is size of the string.
**Auxiliary Space: O(2n), to store all possible partition of string.