Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In - C++ Programming Tutorial
C++ Course / Data Structures / Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In

Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In

BLUF: Mastering Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In

C++ is renowned for its efficiency. Learn how Check If The Concatenation Of Splitted Substrings Of Two Given Strings Forms A Palindrome Or Not In enables low-level control and high-performance computing in the tutorial below.

Introduction

Palindrome verification is a frequent task in programming, commonly encountered in various problem-solving scenarios. Within the context of this discussion, palindromes hold significance as they represent sequences within strings that are identical when read forwards or backwards, like 'madam'. A distinctive palindrome challenge awaits us here, where we aim to address it using C++. The task involves receiving two strings and determining whether it is possible to 'split' them in a manner that upon recombination, they form palindromes. This process essentially involves exploring string division, combination, and palindrome creation.

Problem Statement

Define two strings, s1 and s2. Our objective is to split both strings at any index, take one half from each, and combine them to form a new string. This resulting string must be assessed to determine if it is a palindrome. If either of the original strings can form a palindrome when combined in this manner, the function should return true; otherwise, it should return false.

Example

Let's consider a scenario to demonstrate the issue:

Program 1:

Example

#include <iostream>
#include <string>

bool isPalindrome(const std::string& str) {
    int left = 0;
    int right = str.size() - 1;
    while (left < right) {
        if (str[left] != str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

bool canFormPalindromeBySplitting(const std::string& s1, const std::string& s2) {
    int n = s1.size();
    for (int i = 0; i <= n; i++) {
        // Split s1 and s2 at index i
        std::string s1Prefix = s1.substr(0, i);
        std::string s1Suffix = s1.substr(i);
        std::string s2Prefix = s2.substr(0, i);
        std::string s2Suffix = s2.substr(i);

        // Concatenate parts and check if they form a palindrome
        if (isPalindrome(s1Prefix + s2Suffix) || isPalindrome(s2Prefix + s1Suffix)) {
            return true;
        }
    }
    return false;
}

int main() {
    std::string s1 = "abcba";
    std::string s2 = "xyzzyx";
    
    if (canFormPalindromeBySplitting(s1, s2)) {
        std::cout << "Yes, a palindromic combination can be formed." << std::endl;
    } else {
        std::cout << "No, no palindromic combination can be formed." << std::endl;
    }

    return 0;
}

Output:

Output

Yes, a palindromic combination can be formed.

Explanation

  • Function isPalindrome: This function helps check if the string with a single centre can be a palindrome by checking the string from the starting and the ending towards the centre of the string.
  • Function canFormPalindromeBySplitting: This main function breaks the string into two parts and join joins them together to find if there are palindromic combinations through by checking the isPalindrome function.
  • Main Function: Initializes the strings s1 and s2 and uses the function canFormPalindromeBySplitting to check whether the passed strings can form a valid palindrome.
  • Complexity Analysis

  • Time Complexity: O(n2), where n is the size of the string arrays. Go through the possible splits and check each risk for the single and all possible combinations of the allies.
  • Space Complexity: O(n) because of the carving of the substrings in every round.
  • Program 2:

Example

#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>

// Function to check if a string is a palindrome
bool isPalindrome(const std::string& str) {
    int left = 0;
    int right = str.size() - 1;
    while (left < right) {
        if (str[left] != str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

// Helper function to split and concatenate
void generatePalindromicCombinations(const std::string& s1, const std::string& s2, int min_palindromic_combinations, 
                                     std::unordered_set<std::string>& palindromicCombinations, 
                                     int depth, int maxDepth) {
    int n = s1.size();
    int m = s2.size();

    // Stop if the required number of palindromic combinations is reached
    if (palindromicCombinations.size() >= min_palindromic_combinations) return;

    // Split each string up to a certain depth
    for (int i = 1; i < n && i < m && depth <= maxDepth; i++) {
        std::string s1Prefix = s1.substr(0, i);
        std::string s1Suffix = s1.substr(i);
        std::string s2Prefix = s2.substr(0, i);
        std::string s2Suffix = s2.substr(i);

        // Concatenate in different orders and check for palindrome
        std::vector<std::string> combinations = {
            s1Prefix + s2Suffix,
            s2Prefix + s1Suffix,
            s1Suffix + s2Prefix,
            s2Suffix + s1Prefix
        };

        for (const auto& comb : combinations) {
            if (isPalindrome(comb)) {
                palindromicCombinations.insert(comb);
            }
        }

        // Recursive call to increase depth and explore further splits
        generatePalindromicCombinations(s1Suffix, s2Suffix, min_palindromic_combinations, palindromicCombinations, depth + 1, maxDepth);
    }
}

// Main function to check if the minimum number of palindromic combinations can be formed
bool canFormMultiplePalindromicPatterns(const std::string& s1, const std::string& s2, int min_palindromic_combinations) {
    std::unordered_set<std::string> palindromicCombinations;
    int maxDepth = 3; // Maximum recursion depth for splits (adjustable based on problem complexity)

    // Generate palindromic combinations
    generatePalindromicCombinations(s1, s2, min_palindromic_combinations, palindromicCombinations, 1, maxDepth);

    // Check if we reached the required count
    return palindromicCombinations.size() >= min_palindromic_combinations;
}

int main() {
    std::string s1 = "abaxyz";
    std::string s2 = "zyxba";
    int min_palindromic_combinations = 3;

    if (canFormMultiplePalindromicPatterns(s1, s2, min_palindromic_combinations)) {
        std::cout << "Yes, at least " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    } else {
        std::cout << "No, less than " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    }

    return 0;
}

Output:

Output

Yes, at least 3 palindromic combinations can be formed.

Explanation:

  • isPalindrome Function: Confirms whether the string that's been provided is the same when read from either direction.
  • generatePalindromicCombinations Function: This procedure recursively cuts s1 and s2 at varying lengths, sequences the segments in all permutations, and then observes whether any palindrome has formed. Each set of boolean values makes sure that whenever a new palindrome is detected, it's added to ensure none were left behind. In situations where there is no need for additional palindromic pairs, the ordering terminates quickly.
  • The function canFormMultiplePalindromicPatterns: This function sets the parameters for the recursive depth and the required number of combinations, invokes the recursive method, and, at last, verifies whether the intended count of palindromic patterns has been achieved.
  • Complexity Analysis

  • Time Complexity: The complexity increases with the recursive splits to O (n m D), with n and m being the length of s1 and s2, respectively, while D is the recursion depth in which splits occur.
  • Space Complexity: The size of the space complexity for this study is O(P) due to the storage of unique combinations of the palindromic pattern combinations with respect to the number of fragments, P, of the global palindromic patterns identified in this work.
  • Program 3:

Example

#include <iostream>
#include <string>
#include <unordered_set>

bool isPalindrome(const std::string& str) {
    int left = 0, right = str.size() - 1;
    while (left < right) {
        if (str[left] != str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

bool checkPalindromeCombinations(const std::string& s1, const std::string& s2, int min_palindromic_combinations) {
    int n = s1.size();
    std::unordered_set<std::string> uniquePalindromes;

    // Check combinations of s1 prefixes and s2 suffixes
    for (int i = 0; i <= n; i++) {
        std::string prefix = s1.substr(0, i);
        std::string suffix = (i < n) ? s2.substr(i) : "";  // Avoid out-of-range

        if (isPalindrome(prefix + suffix)) {
            uniquePalindromes.insert(prefix + suffix);
            if (uniquePalindromes.size() >= min_palindromic_combinations) return true;
        }
    }

    // Check combinations of s2 prefixes and s1 suffixes
    for (int i = 0; i <= n; i++) {
        std::string prefix = s2.substr(0, i);
        std::string suffix = (i < n) ? s1.substr(i) : "";  // Avoid out-of-range

        if (isPalindrome(prefix + suffix)) {
            uniquePalindromes.insert(prefix + suffix);
            if (uniquePalindromes.size() >= min_palindromic_combinations) return true;
        }
    }

    return uniquePalindromes.size() >= min_palindromic_combinations;
}

int main() {
    std::string s1 = "abaxyz";
    std::string s2 = "zyxba";
    int min_palindromic_combinations = 3;

    if (checkPalindromeCombinations(s1, s2, min_palindromic_combinations)) {
        std::cout << "Yes, at least " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    } else {
        std::cout << "No, less than " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    }

    return 0;
}

Output:

Output

Yes, at least 3 palindromic combinations can be formed.

Explanation:

  • Use two pointers, left and right, starting at the beginning of s1 and the end of s2 (or vice versa).
  • Check if combining prefixes of s1 with suffixes of s2 forms a palindrome.
  • Similarly, check suffixes of s1 combined with prefixes of s2.
  • Move the pointers inward until a certain depth or stop once a minimum number of palindromic combinations is found.

This minimizes complexity by steering clear of redundant recursive invocations and substring manipulations.

Program 4:

If there is a requirement to validate numerous palindromic substrings within s1 and s2, one effective approach is to employ dynamic programming for precomputing palindromic substrings in both strings. This preparation step enhances the efficiency of subsequent palindrome validations.

Example

#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>

// Check if a given string is a palindrome
bool isPalindrome(const std::string& str) {
    int left = 0, right = str.size() - 1;
    while (left < right) {
        if (str[left] != str[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

// Compute a DP table to determine palindromic substrings in a string
std::vector<std::vector<bool>> computePalindromeDP(const std::string& s) {
    int n = s.size();
    std::vector<std::vector<bool>> dp(n, std::vector<bool>(n, false));

    for (int i = 0; i < n; i++) dp[i][i] = true;
    for (int i = 0; i < n - 1; i++) {
        dp[i][i + 1] = (s[i] == s[i + 1]);
    }

    for (int len = 3; len <= n; len++) {
        for (int i = 0; i <= n - len; i++) {
            int j = i + len - 1;
            dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
        }
    }

    return dp;
}

// Check if at least a certain number of palindromic combinations can be formed
bool canFormPalindromicPatternsDP(const std::string& s1, const std::string& s2, int min_palindromic_combinations) {
    int n = s1.size();
    auto dp1 = computePalindromeDP(s1);
    auto dp2 = computePalindromeDP(s2);

    std::unordered_set<std::string> palindromicCombinations;

    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            if (dp1[i][j]) {
                std::string prefix = s1.substr(i, j - i + 1);
                for (int k = 0; k < n; k++) {
                    std::string combined = prefix + s2.substr(k);
                    if (isPalindrome(combined)) {
                        palindromicCombinations.insert(combined);
                        if (palindromicCombinations.size() >= min_palindromic_combinations) return true;
                    }
                }
            }
        }
    }
    return false;
}

int main() {
    std::string s1 = "abaxyz";
    std::string s2 = "zyxba";
    int min_palindromic_combinations = 3;

    if (canFormPalindromicPatternsDP(s1, s2, min_palindromic_combinations)) {
        std::cout << "Yes, at least " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    } else {
        std::cout << "No, less than " << min_palindromic_combinations << " palindromic combinations can be formed." << std::endl;
    }

    return 0;
}

Output:

Output

Yes, at least 3 palindromic combinations can be formed.

Explanation:

  • Use dynamic programming to create a 2D table for each string, where dpi is true if the substring s[i:j+1] is a palindrome.
  • With precomputed palindromic substrings, quickly check valid combinations of substrings from s1 and s2.
  • This allows us to avoid repeatedly checking for palindromic properties and directly focus on combinations.

This method can minimize repetitive checks for palindrome characteristics and enhance performance when dealing with longer strings.

Conclusion:

A fascinating challenge in creating palindromic patterns involves combining substrings from two specified strings. This task requires manipulating strings, confirming their palindromic nature, and managing substring operations under limited resources. While a straightforward method may suffice initially, future optimization is crucial for efficient searching in extensive strings and more complex scenarios.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience