最长可能的分块回文
给定一个字符串,任务是返回其最长可能的分块回文的长度。当它不是由字符串的字符组成时,它表示由子字符串组成的回文。为了更好地理解,请查看示例示例:
Input : ghiabcdefhelloadamhelloabcdefghi
Output : 7
(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)
Input : merchant
Output : 1
(merchant)
Input : antaprezatepzapreanta
Output : 11
(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)
Input : geeksforgeeks
Output : 3
(geeks)(for)(geeks)
整个想法是从左右递归地创建块。 如您所见,我们可以匹配来自左侧块的子字符串,并将其与精确的右侧块匹配。一旦我们得到一个匹配,我们递归地计算剩余字符串中可能最长的分块回文的长度。一旦没有留下任何字符串或找不到更多有效的分块部分,我们就结束递归。
Java
/* Java program to find the length of longest palindromic
chunk */
import java.util.*;
import java.lang.*;
import java.io.*;
class LongestPalindromicChunk
{
// Here s is the string whose LCP is needed
// ln is length of string evaluated till now
// and str is original string
private static int LPCRec(String curr_str, int count,
int len, String str)
{
// if there is noting at all!!
if (curr_str == null || curr_str.isEmpty())
return (0);
// if a single letter is left out
if (curr_str.length() <= 1)
{
if (count != 0 && str.length() - len <= 1)
return (count + 1);
else
return (1);
}
// for each length of substring chunk in string
int n = curr_str.length();
for (int i = 0; i < n/2; i++)
{
// if left side chunk and right side chunk
// are same
if (curr_str.substring(0, i + 1).
equals(curr_str.substring(n-1-i, n)))
{
// Call LCP for the part between the
// chunks and add 2 to the result.
// Length of string evaluated till
// now is increased by (i+1)*2
return LPCRec(curr_str.substring(i+1, n-1-i),
count + 2,
len + (i+1)*2, str);
}
}
return count + 1;
}
// Wrapper over LPCRec()
public static int LPC(String str)
{
return LPCRec(str, 0, 0, str);
}
// driver function
public static void main(String[] args)
{
System.out.println("V : " + LPC("V"));
System.out.println("VOLVO : " + LPC("VOLVO"));
System.out.println("VOLVOV : " + LPC("VOLVOV"));
System.out.println("ghiabcdefhelloadamhelloabcdefghi : " +
LPC("ghiabcdefhelloadamhelloabcdefghi"));
System.out.println("ghiabcdefhelloadamhelloabcdefghik : " +
LPC("ghiabcdefhelloadamhelloabcdefghik"));
System.out.println("antaprezatepzapreanta : " +
LPC("antaprezatepzapreanta"));
}
}
Python3
# Python3 program to find length of
# longest palindromic chunk
# Here curr_str is the string whose
# LCP is needed leng is length of
# string evaluated till now and s
# is original string
def LPCRec(curr_str, count, leng, s):
# If there is nothing at all!!
if not curr_str:
return 0
# If a single letter is left out
if len(curr_str) <= 1:
if count != 0 and len(s) - leng <= 1:
return (count + 1)
else:
return 1
# For each length of substring
# chunk in string
n = len(curr_str)
for i in range(n // 2):
# If left side chunk and right
# side chunk are same
if (curr_str[0 : i + 1] ==
curr_str[n - 1 - i : n]):
# Call LCP for the part between the
# chunks and add 2 to the result.
# Length of string evaluated till
# now is increased by (i+1)*2
return LPCRec(curr_str[i + 1 : n - 1 - i],
count + 2, leng + (i + 1) * 2, s)
return count + 1
# Wrapper over LPCRec()
def LPC(s):
return LPCRec(s, 0, 0, s)
# Driver code
print("V :", LPC("V"))
print("VOLVO :", LPC("VOLVO"))
print("VOLVOV :", LPC("VOLVOV"))
print("ghiabcdefhelloadamhelloabcdefghi :",
LPC("ghiabcdefhelloadamhelloabcdefghi"))
print("ghiabcdefhelloadamhelloabcdefghik :",
LPC("ghiabcdefhelloadamhelloabcdefghik"))
print("antaprezatepzapreanta :",
LPC("antaprezatepzapreanta"))
# This code is contributed by Prateek Gupta
C#
// C# program to find length of
// longest palindromic chunk
using System;
class GFG
{
// Here s is the string whose LCP
// is needed ln is length of string
// evaluated till now and str is
// original string
private static int LPCRec(string curr_str, int count,
int len, string str)
{
// if there is noting at all!!
if (string.ReferenceEquals(curr_str, null) ||
curr_str.Length == 0)
{
return (0);
}
// if a single letter is left out
if (curr_str.Length <= 1)
{
if (count != 0 && str.Length - len <= 1)
{
return (count + 1);
}
else
{
return (1);
}
}
// for each length of substring
// chunk in string
int n = curr_str.Length;
for (int i = 0; i < n / 2; i++)
{
// if left side chunk and right side chunk
// are same
if (curr_str.Substring(0, i + 1).Equals(
curr_str.Substring(n - 1 - i, n - (n - 1 - i))))
{
// Call LCP for the part between the
// chunks and add 2 to the result.
// Length of string evaluated till
// now is increased by (i+1)*2
return LPCRec(curr_str.Substring(i + 1, (n - 1 - i) -
(i + 1)), count + 2, len + (i + 1) * 2, str);
}
}
return count + 1;
}
// Wrapper over LPCRec()
public static int LPC(string str)
{
return LPCRec(str, 0, 0, str);
}
// Driver Code
public static void Main(string[] args)
{
Console.WriteLine("V : " + LPC("V"));
Console.WriteLine("VOLVO : " + LPC("VOLVO"));
Console.WriteLine("VOLVOV : " + LPC("VOLVOV"));
Console.WriteLine("ghiabcdefhelloadamhelloabcdefghi : " +
LPC("ghiabcdefhelloadamhelloabcdefghi"));
Console.WriteLine("ghiabcdefhelloadamhelloabcdefghik : " +
LPC("ghiabcdefhelloadamhelloabcdefghik"));
Console.WriteLine("antaprezatepzapreanta : " +
LPC("antaprezatepzapreanta"));
}
}
// This code is contributed by Shrikant13
Javascript
CPP
#include
#include
#include
using namespace std;
unordered_map mem;
int process(string& s, int l, int r) {
int ans = 1;
if (l > r)
return 0;
// check if we've already solved this
if (mem.find(s.substr(l, r-l+1)) != mem.end())
return mem[s.substr(l, r-l+1)];
for (int len = 1; len <= (r-l+1)/2; len++) {
if (s.substr(l, len) == s.substr(r-len+1, len))
ans = max(ans, 2 + process(s, l+len, r-len));
}
// remember result for future
mem[s.substr(l, r-l+1)] = ans;
return ans;
}
int LPC(string s) {
return process(s, 0, s.length()-1);
}
int main() {
cout << LPC("aaaaabaababbaabaaababababababababbbbaaaaa") << endl;
return 0;
}
输出:
V : 1
VOLVO : 3
VOLVOV : 5
ghiabcdefhelloadamhelloabcdefghi : 7
ghiabcdefhelloadamhelloabcdefghik : 1
antaprezatepzapreanta : 11
以下是针对上述问题的带有记忆功能的 C++ 实现。
CPP
#include
#include
#include
using namespace std;
unordered_map mem;
int process(string& s, int l, int r) {
int ans = 1;
if (l > r)
return 0;
// check if we've already solved this
if (mem.find(s.substr(l, r-l+1)) != mem.end())
return mem[s.substr(l, r-l+1)];
for (int len = 1; len <= (r-l+1)/2; len++) {
if (s.substr(l, len) == s.substr(r-len+1, len))
ans = max(ans, 2 + process(s, l+len, r-len));
}
// remember result for future
mem[s.substr(l, r-l+1)] = ans;
return ans;
}
int LPC(string s) {
return process(s, 0, s.length()-1);
}
int main() {
cout << LPC("aaaaabaababbaabaaababababababababbbbaaaaa") << endl;
return 0;
}