// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Function to find largest palindrome
// possible from S and P after rearranging
// characters to make palindromic string T
static String mergePalindromes(StringBuilder S,
StringBuilder P)
{
// Using unordered_map to store
// frequency of elements
// mapT will have freq of elements of T
Map<Character, Integer> mapS = new HashMap<>(),
mapP = new HashMap<>(),
mapT = new HashMap<>();
// Size of both the strings
int n = S.length(), m = P.length();
for(int i = 0; i < n; i++)
{
mapS.put(S.charAt(i),
mapS.getOrDefault(S.charAt(i), 0) + 1);
}
for(int i = 0; i < m; i++)
{
mapP.put(P.charAt(i),
mapP.getOrDefault(P.charAt(i), 0) + 1);
}
// Take all character in mapT which
// occur even number of times in
// respective strings & simultaneously
// update number of characters left in map
for(char i = 'a'; i <= 'z'; i++)
{
if (mapS.getOrDefault(i, 0) % 2 == 0)
{
mapT.put(i,mapT.getOrDefault(i, 0) +
mapS.getOrDefault(i, 0));
mapS.put(i, 0);
}
else
{
mapT.put(i,mapT.getOrDefault(i, 0) +
mapS.getOrDefault(i, 0) - 1);
mapS.put(i, 1);
}
if (mapP.getOrDefault(i, 0) % 2 == 0)
{
mapT.put(i, mapT.getOrDefault(i, 0) +
mapP.getOrDefault(i, 0));
mapP.put(i, 0);
}
else
{
mapT.put(i, mapT.getOrDefault(i, 0) +
mapP.getOrDefault(i, 0) - 1);
mapP.put(i, 1);
}
}
// Check if a unique character is
// present in both string S and P
int check = 0;
for(char i = 'a'; i <= 'z'; i++)
{
if (mapS.getOrDefault(i, 0) > 0 &&
mapP.getOrDefault(i, 0) > 0)
{
mapT.put(i, mapT.getOrDefault(i, 0) + 2);
check = 1;
break;
}
}
// Making string T in two halves
// half1 - first half
// half2 - second half
StringBuilder half1 = new StringBuilder(),
half2 = new StringBuilder();
for(char i = 'a'; i <= 'z'; i++)
{
for(int j = 0;
(2 * j) < mapT.getOrDefault(i, 0);
j++)
{
half1.append(i);
half2.append(i);
}
}
// Reverse the half2 to attach with half1
// to make palindrome T
StringBuilder tmp = half2.reverse();
// If same unique element is present
// in both S and P, then taking that only
// which is already taken through mapT
if (check == 1)
{
return half1.append(tmp).toString();
}
// If same unique element is not
// present in S and P, then take
// characters that make string T
// lexicographically smallest
for(char i = 'a'; i <= 'z'; i++)
{
if (mapS.getOrDefault(i, 0) > 0 ||
mapP.getOrDefault(i, 0) > 0)
{
half1.append(i);
return half1.append(tmp).toString();
}
}
// If no unique element is
// present in both string S and P
return half1.append(tmp).toString();
}
// Driver code
public static void main (String[] args)
{
// Given two strings S and P
StringBuilder S = new StringBuilder("aeabb");
StringBuilder P = new StringBuilder("dfedf");
// Function call
System.out.println(mergePalindromes(S, P));
}
}
// This code is contributed by offbeat