给定长度为n的字符串s,计算具有不同回文特征类型的子字符串的数量。
回文特征是字符串中的k回文数,其中k处于[0,n)范围内。
当且仅当字符串向后读取与向后读取相同时,它才是1-回文(或简称回文)。
字符串仅在以下情况下为k回文式(k> 1):
1.它的左半部分等于其右半部分。
2.其左半部分和右半部分应为非空(k – 1)回文。长度为’t’的字符串的左半部分是其长度⌊t/2⌋的前缀,而右半部分是相同长度的后缀。
注意:每个子字符串的计数与在字符串出现的次数相同。例如,在字符串“ aaa”中,子字符串“ a”出现3次。
例子 :
Input : abba
Output : 6 1 0 0
Explanation :
"6" 1-palindromes = "a", "b", "b", "a", "bb", "abba".
"1" 2-palindrome = "bb". Because "b" is 1-palindrome
and "bb" has both left and right parts equal.
"0" 3-palindrome and 4-palindrome.
Input : abacaba
Output : 12 4 1 0 0 0 0
Explanation :
"12" 1-palindromes = "a", "b", "a", "c", "a", "b",
"a", "aba", "aca", "aba", "bacab", "abacaba".
"4" 2-palindromes = "aba", "aca", "aba", "abacaba".
Because "a" and "aba" are 1-palindromes.
NOTE : "bacab" is not 2-palindrome as "ba"
is not 1-palindrome. "1" 3-palindrome = "abacaba".
Because is "aba" is 2-palindrome. "0" other
k-pallindromes where 4 < = k < = 7.
方法:取一个字符串s,说它是一个1-回文,然后检查它的左半部分也变成了一个1-回文,那么显然它的右部分将始终等于左部分(因为该字符串也是一个1-回文)回文)将原始字符串设为2回文。现在,类似地,检查字符串的左半部分,它也变成了1回文,然后将左半部分变成了2回文,因此,将原始字符串变成了3回文,依此类推直到仅剩1个字母,或者该部分不是1个回文。
让我们取字符串=“ abacaba”。已知的“算盘”是1-回文。因此,在检查左半部分“ aba”(也是1回文)时,会将“ abacaba”变成2回文。然后,检查“ aba”的左半部分“ a”,它也是1回文。因此,它使“ aba”成为2回文,“ aba”使“ ababaca”成为3回文。因此,换句话说,如果字符串是k回文,那么它也是(k-1)回文,(k-2)回文,依此类推,直到1回文。下面给出了相同的代码,该代码首先检查每个子串(如果它是回文),然后以对数时间递归计算k-回文子串的数目。
下面是上述方法的实现:
C++
// A C++ program which counts different
// palindromic characteristics of a string.
#include
using namespace std;
const int MAX_STR_LEN = 1000;
bool P[MAX_STR_LEN][MAX_STR_LEN];
int Kpal[MAX_STR_LEN];
// A C++ function which checks whether a
// substring str[i..j] of a given string
// is a palindrome or not.
void checkSubStrPal(string str, int n)
{
// P[i][j] = true if substring str
// [i..j] is palindrome, else false
memset(P, false, sizeof(P));
// palindrome of single length
for (int i = 0; i < n; i++)
P[i][i] = true;
// palindrome of length 2
for (int i = 0; i < n - 1; i++)
if (str[i] == str[i + 1])
P[i][i + 1] = true;
// Palindromes of length more then 2.
// This loop is similar to Matrix Chain
// Multiplication. We start with a gap of
// length 2 and fill P table in a way that
// gap between starting and ending indexes
// increases one by one by outer loop.
for (int gap = 2; gap < n; gap++)
{
// Pick starting point for current gap
for (int i = 0; i < n - gap; i++)
{
// Set ending point
int j = gap + i;
// If current string is palindrome
if (str[i] == str[j] && P[i + 1][j - 1])
P[i][j] = true;
}
}
}
// A C++ function which recursively
// counts if a string str [i..j] is
// a k-palindromic string or not.
void countKPalindromes(int i, int j, int k)
{
// terminating condition for a
// string which is a k-palindrome.
if (i == j)
{
Kpal[k]++;
return;
}
// terminating condition for a
// string which is not a k-palindrome.
if (P[i][j] == false)
return;
// increases the counter for the
// string if it is a k-palindrome.
Kpal[k]++;
// mid is middle pointer of
// the string str [i...j].
int mid = (i + j) / 2;
// if length of string which is
// (j - i + 1) is odd than we have
// to subtract one from mid.
// else if even then no change.
if ((j - i + 1) % 2 == 1)
mid--;
// if the string is k-palindrome
// then we check if it is a
// (k+1) - palindrome or not by
// just sending any of one half of
// the string to the Count_k_Palindrome
// function.
countKPalindromes(i, mid, k + 1);
}
void printKPalindromes(string s)
{
// Count of k-palindromes is equal
// to zero initially.
memset(Kpal, 0, sizeof(Kpal));
// Finding all palindromic
// substrings of given string
int n = s.length();
checkSubStrPal(s, n);
// counting k-palindromes for each and
// every substring of given string. .
for (int i = 0; i < n; i++)
for (int j = 0; j < n - i; j++)
countKPalindromes(j, j + i, 1);
// Output the number of K-palindromic
// substrings of a given string.
for (int i = 1; i <= n; i++)
cout << Kpal[i] << " ";
cout << "\n";
}
// Driver code
int main()
{
string s = "abacaba";
printKPalindromes(s);
return 0;
}
Java
// Java program which counts
// different palindromic
// characteristics of a string.
import java.io.*;
class GFG
{
static int MAX_STR_LEN = 1000;
static boolean P[][] =
new boolean[MAX_STR_LEN][MAX_STR_LEN];
static int []Kpal =
new int[MAX_STR_LEN];
// function which checks
// whether a substring
// str[i..j] of a given
// string is a palindrome or not.
static void checkSubStrPal(String str,
int n)
{
// P[i,j] = true if substring
// str [i..j] is palindrome,
// else false
for (int i = 0; i < MAX_STR_LEN; i++)
{
for (int j = 0; j < MAX_STR_LEN; j++)
P[i][j] = false;
Kpal[i] = 0;
}
// palindrome of
// single length
for (int i = 0; i < n; i++)
P[i][i] = true;
// palindrome of
// length 2
for (int i = 0; i < n - 1; i++)
if (str.charAt(i) == str.charAt(i + 1))
P[i][i + 1] = true;
// Palindromes of length
// more then 2. This loop
// is similar to Matrix
// Chain Multiplication.
// We start with a gap of
// length 2 and fill P table
// in a way that gap between
// starting and ending indexes
// increases one by one by
// outer loop.
for (int gap = 2; gap < n; gap++)
{
// Pick starting point
// for current gap
for (int i = 0; i < n - gap; i++)
{
// Set ending point
int j = gap + i;
// If current string
// is palindrome
if (str.charAt(i) == str.charAt(j) &&
P[i + 1][j - 1])
P[i][j] = true;
}
}
}
// A function which recursively
// counts if a string str [i..j] is
// a k-palindromic string or not.
static void countKPalindromes(int i, int j,
int k)
{
// terminating condition
// for a string which is
// a k-palindrome.
if (i == j)
{
Kpal[k]++;
return;
}
// terminating condition for
// a string which is not a
// k-palindrome.
if (P[i][j] == false)
return;
// increases the counter
// for the string if it
// is a k-palindrome.
Kpal[k]++;
// mid is middle pointer of
// the string str [i...j].
int mid = (i + j) / 2;
// if length of string which
// is (j - i + 1) is odd than
// we have to subtract one
// from mid else if even then
// no change.
if ((j - i + 1) % 2 == 1)
mid--;
// if the string is k-palindrome
// then we check if it is a
// (k+1) - palindrome or not
// by just sending any of one
// half of the string to the
// Count_k_Palindrome function.
countKPalindromes(i, mid, k + 1);
}
static void printKPalindromes(String s)
{
// Finding all palindromic
// substrings of given string
int n = s.length();
checkSubStrPal(s, n);
// counting k-palindromes for
// each and every substring
// of given string. .
for (int i = 0; i < n; i++)
for (int j = 0; j < n - i; j++)
countKPalindromes(j, j + i, 1);
// Output the number of
// K-palindromic substrings
// of a given string.
for (int i = 1; i <= n; i++)
System.out.print(Kpal[i] + " ");
System.out.println();
}
// Driver code
public static void main(String args[])
{
String s = "abacaba";
printKPalindromes(s);
}
}
// This code is contributd by
// Manish Shaw(manishshaw1)
Python3
# Python program which counts
# different palindromic
# characteristics of a string.
MAX_STR_LEN = 1000;
P = [[0 for x in range(MAX_STR_LEN)]
for y in range(MAX_STR_LEN)] ;
for i in range(0, MAX_STR_LEN) :
for j in range(0, MAX_STR_LEN) :
P[i][j] = False;
Kpal = [0] * MAX_STR_LEN;
# def which checks
# whether a substr[i..j]
# of a given is a
# palindrome or not.
def checkSubStrPal(str, n) :
global P, Kpal, MAX_STR_LEN;
# P[i,j] = True if substr
# [i..j] is palindrome,
# else False
for i in range(0, MAX_STR_LEN) :
for j in range(0, MAX_STR_LEN) :
P[i][j] = False;
Kpal[i] = 0;
# palindrome of
# single length
for i in range(0, n) :
P[i][i] = True;
# palindrome of
# length 2
for i in range(0, n - 1) :
if (str[i] == str[i + 1]) :
P[i][i + 1] = True;
# Palindromes of length more
# then 2. This loop is similar
# to Matrix Chain Multiplication.
# We start with a gap of length
# 2 and fill P table in a way
# that gap between starting and
# ending indexes increases one
# by one by outer loop.
for gap in range(2, n) :
# Pick starting point
# for current gap
for i in range(0, n - gap) :
# Set ending point
j = gap + i;
# If current string
# is palindrome
if (str[i] == str[j] and
P[i + 1][j - 1]) :
P[i][j] = True;
# A Python def which
# recursively counts if
# a str [i..j] is a
# k-palindromic or not.
def countKPalindromes(i, j, k) :
global Kpal, P;
# terminating condition
# for a which is a
# k-palindrome.
if (i == j) :
Kpal[k] = Kpal[k] + 1;
return;
# terminating condition
# for a which is not a
# k-palindrome.
if (P[i][j] == False) :
return;
# increases the counter
# for the if it is a
# k-palindrome.
Kpal[k] = Kpal[k] + 1;
# mid is middle pointer
# of the str [i...j].
mid = int((i + j) / 2);
# if length of which is
# (j - i + 1) is odd than
# we have to subtract one
# from mid else if even
# then no change.
if ((j - i + 1) % 2 == 1) :
mid = mid - 1;
# if the is k-palindrome
# then we check if it is a
# (k+1) - palindrome or not
# by just sending any of
# one half of the to the
# Count_k_Palindrome def.
countKPalindromes(i, mid, k + 1);
def printKPalindromes(s) :
global P, Kpal, MAX_STR_LEN;
# Finding all palindromic
# substrings of given string
n = len(s);
checkSubStrPal(s, n);
# counting k-palindromes
# for each and every sub
# of given string. .
for i in range(0, n) :
for j in range(0, n - i) :
countKPalindromes(j, j + i, 1);
# Output the number of
# K-palindromic substrings
# of a given string.
for i in range(1, n + 1) :
print (Kpal[i], end=" ");
print();
# Driver code
s = "abacaba";
printKPalindromes(s);
# This code is contributd by
# Manish Shaw(manishshaw1)
C#
// C# program which counts
// different palindromic
// characteristics of a string.
using System;
class GFG
{
static int MAX_STR_LEN = 1000;
static bool [,]P = new bool[MAX_STR_LEN,
MAX_STR_LEN];
static int []Kpal = new int[MAX_STR_LEN];
// function which checks whether
// a substring str[i..j] of a
// given string is a palindrome or not.
static void checkSubStrPal(string str,
int n)
{
// P[i,j] = true if substring str
// [i..j] is palindrome, else false
for (int i = 0; i < MAX_STR_LEN; i++)
{
for (int j = 0; j < MAX_STR_LEN; j++)
P[i, j] = false;
Kpal[i] = 0;
}
// palindrome of single length
for (int i = 0; i < n; i++)
P[i, i] = true;
// palindrome of length 2
for (int i = 0; i < n - 1; i++)
if (str[i] == str[i + 1])
P[i, i + 1] = true;
// Palindromes of length more
// then 2. This loop is similar
// to Matrix Chain Multiplication.
// We start with a gap of length 2
// and fill P table in a way that
// gap between starting and ending
// indexes increases one by one by
// outer loop.
for (int gap = 2; gap < n; gap++)
{
// Pick starting point
// for current gap
for (int i = 0; i < n - gap; i++)
{
// Set ending point
int j = gap + i;
// If current string
// is palindrome
if (str[i] == str[j] &&
P[i + 1, j - 1])
P[i, j] = true;
}
}
}
// A C++ function which recursively
// counts if a string str [i..j] is
// a k-palindromic string or not.
static void countKPalindromes(int i, int j,
int k)
{
// terminating condition for a
// string which is a k-palindrome.
if (i == j)
{
Kpal[k]++;
return;
}
// terminating condition for
// a string which is not a
// k-palindrome.
if (P[i, j] == false)
return;
// increases the counter for the
// string if it is a k-palindrome.
Kpal[k]++;
// mid is middle pointer of
// the string str [i...j].
int mid = (i + j) / 2;
// if length of string which is
// (j - i + 1) is odd than we have
// to subtract one from mid.
// else if even then no change.
if ((j - i + 1) % 2 == 1)
mid--;
// if the string is k-palindrome
// then we check if it is a
// (k+1) - palindrome or not
// by just sending any of one
// half of the string to the
// Count_k_Palindrome function.
countKPalindromes(i, mid, k + 1);
}
static void printKPalindromes(string s)
{
// Finding all palindromic
// substrings of given string
int n = s.Length;
checkSubStrPal(s, n);
// counting k-palindromes for each and
// every substring of given string. .
for (int i = 0; i < n; i++)
for (int j = 0; j < n - i; j++)
countKPalindromes(j, j + i, 1);
// Output the number of K-palindromic
// substrings of a given string.
for (int i = 1; i <= n; i++)
Console.Write(Kpal[i] + " ");
Console.WriteLine();
}
// Driver code
static void Main()
{
string s = "abacaba";
printKPalindromes(s);
}
}
// This code is contributd by
// Manish Shaw(manishshaw1)
PHP
12 4 1 0 0 0 0
时间复杂度: O( )
辅助空间: O( )