📌  相关文章
📜  通过连接和重新排列等长字符串形成的最长回文

📅  最后修改于: 2021-05-17 18:33:04             🧑  作者: Mango

给定一个数组nrr [] ,该数组由相等长度MN个字符串组成,任务是通过串联字符串来创建最长回文。也可以从给定的字符串集中重新排序和丢弃某些字符串。

例子:

观察:让我们假设,我们选择了从给定数组某个k字符串并选择那些ķ字符串之后,我们得到的是一个回文字符串。然后需要对可能的K值进行观察:

  • K是偶数:然后对于每个整数x(1 <= x <= K / 2):
    Sx = rev(SK - x + 1)
    

    例如,如果构成最长回文的字符串是S 1 =“ tab”,S 2 =“ ab”,S 3 =“ ba”,S 4 =“ bat”。在此,K = 4。因此,S 1 = rev(S 4 ),S 2 = rev(S 3 )。

  • K是奇数:除上述观察之外,中间字符串S (K + 1)/ 2是回文。

方法:显然,从上面的观察中,要获得最大的回文率,给定的数组还必须包含字符串的反面。因此,对于每个字符串,我们都会发现是否存在另一个与之相反的字符串。如果存在,则将这对字符串分别添加到左端和右端。如果有一个或多个回文本身的字符串,请选择其中任何一个并将其放在中间。

下面是上述方法的实现:

C++
// C++ program to find the
// Longest palindrome that can be formed
// by concatenating and reordering
// given N strings of equal length
#include 
using namespace std;
  
// Function to print the longest palindrome
void printPalindrome(vector left,
                     string mid, vector right)
{
    // Printing every string in left vector
    for (string x : left)
        cout << x;
  
    // Printing the palindromic string
    // in the middle
    cout << mid;
  
    // Printing the reverse of the right vector
    // to make the final output palindromic
    reverse(right.begin(), right.end());
    for (string x : right)
        cout << x;
  
    cout << endl;
}
  
// Function to find and print the
// longest palindrome that can be formed
void findPalindrome(vector& S, int N, int M)
{
    set dict;
    for (int i = 0; i < M; i++) {
        cin >> S[i];
        // Inserting each string in the set
        dict.insert(S[i]);
    }
  
    // Vectors to add the strings
    // in the left and right side
    vector left, right;
  
    // To add the already present palindrome
    // string in the middle of the solution
    string mid;
  
    // Iterating through all the given strings
    for (int i = 0; i < N; i++) {
        string t = S[i];
        reverse(t.begin(), t.end());
  
        // If the string is a palindrome
        // it is added in the middle
        if (t == S[i])
            mid = t;
  
        // Checking if the reverse
        // of the string is already
        // present in the set
        else if (dict.find(t) != dict.end()) {
            left.push_back(S[i]);
            right.push_back(t);
            dict.erase(S[i]);
            dict.erase(t);
        }
    }
  
    printPalindrome(left, mid, right);
}
  
// Driver code
int main()
{
    vector S{ "tab", "one", "bat" };
    int M = 3;
    int N = S.size();
    findPalindrome(S, N, M);
}


Java
// Java program to find the
// Longest palindrome that can be formed
// by concatenating and reordering
// given N Strings of equal length
import java.util.*;
  
class GFG{
   
// Function to print the longest palindrome
static void printPalindrome(Vector left,
                     String mid, Vector right)
{
    // Printing every String in left vector
    for (String x : left)
        System.out.print(x);
   
    // Printing the palindromic String
    // in the middle
    System.out.print(mid);
   
    // Printing the reverse of the right vector
    // to make the final output palindromic
    Collections.reverse(right);
    for (String x : right)
        System.out.print(x);
   
    System.out.println();
}
   
// Function to find and print the
// longest palindrome that can be formed
static void findPalindrome(Vector S, int N, int M)
{
    HashSet dict = new HashSet();
    for (int i = 0; i < M; i++) {
        // Inserting each String in the set
        dict.add(S.get(i));
    }
   
    // Vectors to add the Strings
    // in the left and right side
    Vector left = new Vector(), right = new Vector();
   
    // To add the already present palindrome
    // String in the middle of the solution
    String mid="";
   
    // Iterating through all the given Strings
    for (int i = 0; i < N; i++) {
        String t = S.get(i);
        t = reverse(t);
   
        // If the String is a palindrome
        // it is added in the middle
        if (t == S.get(i))
            mid = t;
   
        // Checking if the reverse
        // of the String is already
        // present in the set
        else if (dict.contains(t)) {
            left.add(S.get(i));
            right.add(t);
            dict.remove(S.get(i));
            dict.remove(t);
        }
    }
   
    printPalindrome(left, mid, right);
}
static String reverse(String input) {
    char[] a = input.toCharArray();
    int l, r = a.length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.valueOf(a);
} 
// Driver code
public static void main(String[] args)
{
    String arr[] = { "tab", "one", "bat" };
    Vector S = new Vector(Arrays.asList(arr));
    int M = 3;
    int N = S.size();
    findPalindrome(S, N, M);
}
}
  
// This code contributed by PrinciRaj1992


Python3
# Function to print the longest palindrome
def printPalindrome(left,mid,right):
  
    # Printing every string in left vector
    for x in left:
        print(x, end="")
  
    # Printing the palindromic string
    # in the middle
    print(mid, end="")
  
    # Printing the reverse of the right vector
    # to make the final output palindromic
    right = right[::-1]
    for x in right:
        print(x, end = "")
  
    print('\n', end = "")
  
# Function to find and print the
# longest palindrome that can be formed
def findPalindrome(S, N, M):
    d = set()
    for i in range(M):
        # Inserting each string in the set
        d.add(S[i])
  
    # Vectors to add the strings
    # in the left and right side
    left = []
    right = []
  
    # To add the already present palindrome
    # string in the middle of the solution
    mid = ""
  
    # Iterating through all the given strings
    for i in range(N):
        t = S[i]
        t = t[::-1]
  
        # If the string is a palindrome
        # it is added in the middle
        if (t == S[i]):
            mid = t
  
        # Checking if the reverse
        # of the string is already
        # present in the set
        elif (t in d):
            left.append(S[i])
            right.append(t)
            d.remove(S[i])
            d.remove(t)
  
    printPalindrome(left, mid, right)
  
# Driver code
if __name__ == '__main__':
    S = ["tab", "one", "bat"]
    M = 3
    N = len(S)
    findPalindrome(S, N, M)
  
# This code is contributed by Surendra_Gangwar


C#
// C# program to find the
// longest palindrome that can be formed
// by concatenating and reordering
// given N Strings of equal length
using System;
using System.Collections.Generic;
  
class GFG{
  
// Function to print the longest palindrome
static void printPalindrome(List left,
                    String mid, List right)
{
    // Printing every String in left vector
    foreach (String x in left)
        Console.Write(x);
  
    // Printing the palindromic String
    // in the middle
    Console.Write(mid);
  
    // Printing the reverse of the right vector
    // to make the readonly output palindromic
    right.Reverse();
    foreach (String x in right)
        Console.Write(x);
  
    Console.WriteLine();
}
  
// Function to find and print the
// longest palindrome that can be formed
static void findPalindrome(List S, int N, int M)
{
    HashSet dict = new HashSet();
    for (int i = 0; i < M; i++) {
          
        // Inserting each String in the set
        dict.Add(S[i]);
    }
  
    // Lists to add the Strings
    // in the left and right side
    List left = new List(), 
    right = new List();
  
    // To add the already present palindrome
    // String in the middle of the solution
    String mid="";
  
    // Iterating through all the given Strings
    for (int i = 0; i < N; i++) {
        String t = S[i];
        t = reverse(t);
  
        // If the String is a palindrome
        // it is added in the middle
        if (t == S[i])
            mid = t;
  
        // Checking if the reverse
        // of the String is already
        // present in the set
        else if (dict.Contains(t)) {
            left.Add(S[i]);
            right.Add(t);
            dict.Remove(S[i]);
            dict.Remove(t);
        }
    }
  
    printPalindrome(left, mid, right);
}
static String reverse(String input) {
    char[] a = input.ToCharArray();
    int l, r = a.Length - 1;
    for (l = 0; l < r; l++, r--) {
        char temp = a[l];
        a[l] = a[r];
        a[r] = temp;
    }
    return String.Join("",a);
} 
  
// Driver code
public static void Main(String[] args)
{
    String []arr = { "tab", "one", "bat" };
    List S = new List(arr);
    int M = 3;
    int N = S.Count;
    findPalindrome(S, N, M);
}
}
  
// This code is contributed by Princi Singh


输出:
tabbat