📌  相关文章
📜  计算给定字符串的不重叠回文子字符串对

📅  最后修改于: 2021-06-25 14:02:43             🧑  作者: Mango

给定字符串S。任务是计算回文子字符串S1S2的不重叠对,以使字符串应为S1 [L1…R1]S2 [L2…R2] ,其中0≤L1≤R1 。任务是计算不重叠的回文子字符串对的数量。

例子:

方法:我们可以使用动态编程来解决上述问题。我们最初可以创建DP表,该表存储substring [i….j]是否为回文。我们维护一个以自下而上的方式填充的布尔值dp [n] [n] 。如果子字符串是回文,则dp [i] [j]的值为true,否则为false。为了计算dp [i] [j],我们首先检查dp [i + 1] [j-1]的值,如果该值为true且s [i]s [j]相同,则使dp [i] [j]是。否则,将dp [i] [j]的值设为false。此后可以遵循以下步骤来获取对数。

  • 创建一个left []数组,其中left [i]存储包括i在内的索引i上的回文数。
  • 创建一个right []数组,其中right [i]存储包括i在内的索引i右边的回文数。
  • 0迭代到length-1并添加left [i] * right [i + 1] 。每个索引的总和就是所需的对数。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define N 100
  
// Pre-processing function
void pre_process(bool dp[N][N], string s)
{
  
    // Get the size of the string
    int n = s.size();
  
    // Initially mark every
    // position as false
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++)
            dp[i][j] = false;
    }
  
    // For the length
    for (int j = 1; j <= n; j++) {
  
        // Iterate for every index with
        // length j
        for (int i = 0; i <= n - j; i++) {
  
            // If the length is less than 2
            if (j <= 2) {
  
                // If characters are equal
                if (s[i] == s[i + j - 1])
                    dp[i][i + j - 1] = true;
            }
  
            // Check for equal
            else if (s[i] == s[i + j - 1])
                dp[i][i + j - 1] = dp[i + 1][i + j - 2];
        }
    }
}
  
// Function to return the number of pairs
int countPairs(string s)
{
  
    // Create the dp table initially
    bool dp[N][N];
    pre_process(dp, s);
    int n = s.length();
  
    // Declare the left array
    int left[n];
    memset(left, 0, sizeof left);
  
    // Declare the right array
    int right[n];
    memset(right, 0, sizeof right);
  
    // Initially left[0] is 1
    left[0] = 1;
  
    // Count the number of palindrome
    // pairs to the left
    for (int i = 1; i < n; i++) {
  
        for (int j = 0; j <= i; j++) {
  
            if (dp[j][i] == 1)
                left[i]++;
        }
    }
  
    // Initially right most as 1
    right[n - 1] = 1;
  
    // Count the number of palindrome
    // pairs to the right
    for (int i = n - 2; i >= 0; i--) {
  
        right[i] = right[i + 1];
  
        for (int j = n - 1; j >= i; j--) {
  
            if (dp[i][j] == 1)
                right[i]++;
        }
    }
  
    int ans = 0;
  
    // Count the number of pairs
    for (int i = 0; i < n - 1; i++)
        ans += left[i] * right[i + 1];
  
    return ans;
}
  
// Driver code
int main()
{
    string s = "abacaba";
    cout << countPairs(s);
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
  
    static int N = 100;
  
    // Pre-processing function
    static void pre_process(boolean dp[][], char[] s)
    {
  
        // Get the size of the string
        int n = s.length;
  
        // Initially mark every
        // position as false
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                dp[i][j] = false;
            }
        }
  
        // For the length
        for (int j = 1; j <= n; j++)
        {
  
            // Iterate for every index with
            // length j
            for (int i = 0; i <= n - j; i++)
            {
  
                // If the length is less than 2
                if (j <= 2) 
                {
  
                    // If characters are equal
                    if (s[i] == s[i + j - 1])
                    {
                        dp[i][i + j - 1] = true;
                    }
                } 
                // Check for equal
                else if (s[i] == s[i + j - 1])
                {
                    dp[i][i + j - 1] = dp[i + 1][i + j - 2];
                }
            }
        }
    }
  
    // Function to return the number of pairs
    static int countPairs(String s)
    {
  
        // Create the dp table initially
        boolean dp[][] = new boolean[N][N];
        pre_process(dp, s.toCharArray());
        int n = s.length();
  
        // Declare the left array
        int left[] = new int[n];
  
        // Declare the right array
        int right[] = new int[n];
  
        // Initially left[0] is 1
        left[0] = 1;
  
        // Count the number of palindrome
        // pairs to the left
        for (int i = 1; i < n; i++)
        {
  
            for (int j = 0; j <= i; j++) 
            {
  
                if (dp[j][i] == true)
                {
                    left[i]++;
                }
            }
        }
  
        // Initially right most as 1
        right[n - 1] = 1;
  
        // Count the number of palindrome
        // pairs to the right
        for (int i = n - 2; i >= 0; i--)
        {
  
            right[i] = right[i + 1];
  
            for (int j = n - 1; j >= i; j--)
            {
  
                if (dp[i][j] == true)
                {
                    right[i]++;
                }
            }
        }
  
        int ans = 0;
  
        // Count the number of pairs
        for (int i = 0; i < n - 1; i++)
        {
            ans += left[i] * right[i + 1];
        }
  
        return ans;
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        String s = "abacaba";
        System.out.println(countPairs(s));
    }
}
  
// This code contributed by Rajput-Ji


Python3
# Python3 implementation of the approach
N = 100
  
# Pre-processing function
def pre_process(dp, s):
  
    # Get the size of the string
    n = len(s)
  
    # Initially mark every
    # position as false
    for i in range(n):
        for j in range(n):
            dp[i][j] = False
  
    # For the length
    for j in range(1, n + 1):
  
        # Iterate for every index with
        # length j
        for i in range(n - j + 1):
  
            # If the length is less than 2
            if (j <= 2):
  
                # If characters are equal
                if (s[i] == s[i + j - 1]):
                    dp[i][i + j - 1] = True
  
            # Check for equal
            elif (s[i] == s[i + j - 1]):
                dp[i][i + j - 1] = dp[i + 1][i + j - 2]
  
# Function to return the number of pairs
def countPairs(s):
  
    # Create the dp table initially
    dp = [[False for i in range(N)] 
                 for j in range(N)]
    pre_process(dp, s)
    n = len(s)
  
    # Declare the left array
    left = [0 for i in range(n)]
  
    # Declare the right array
    right = [0 for i in range(n)]
  
    # Initially left[0] is 1
    left[0] = 1
  
    # Count the number of palindrome
    # pairs to the left
    for i in range(1, n):
  
        for j in range(i + 1):
  
            if (dp[j][i] == 1):
                left[i] += 1
  
    # Initially right most as 1
    right[n - 1] = 1
  
    # Count the number of palindrome
    # pairs to the right
    for i in range(n - 2, -1, -1):
  
        right[i] = right[i + 1]
  
        for j in range(n - 1, i - 1, -1):
  
            if (dp[i][j] == 1):
                right[i] += 1
  
    ans = 0
  
    # Count the number of pairs
    for i in range(n - 1):
        ans += left[i] * right[i + 1]
  
    return ans
  
# Driver code
s = "abacaba"
print(countPairs(s))
  
# This code is contributed by mohit kumar


PHP
= 0; $i--) 
    { 
        $right[$i] = $right[$i + 1]; 
  
        for ($j = $n - 1; $j >= $i; $j--)
        { 
            if ($dp[$i][$j] == 1) 
                $right[$i]++; 
        } 
    } 
  
    $ans = 0; 
  
    // Count the number of pairs 
    for ($i = 0; $i < $n - 1; $i++) 
        $ans += $left[$i] * $right[$i + 1]; 
  
    return $ans; 
} 
  
// Driver code 
$s = "abacaba"; 
echo countPairs($s); 
  
// This code is contributed by Ryuga
?>


C#
// C# implementation of the approach
using System;
      
class GFG
{
  
    static int N = 100;
  
    // Pre-processing function
    static void pre_process(bool [,]dp, char[] s)
    {
  
        // Get the size of the string
        int n = s.Length;
  
        // Initially mark every
        // position as false
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                dp[i,j] = false;
            }
        }
  
        // For the length
        for (int j = 1; j <= n; j++)
        {
  
            // Iterate for every index with
            // length j
            for (int i = 0; i <= n - j; i++)
            {
  
                // If the length is less than 2
                if (j <= 2) 
                {
  
                    // If characters are equal
                    if (s[i] == s[i + j - 1])
                    {
                        dp[i,i + j - 1] = true;
                    }
                } 
                // Check for equal
                else if (s[i] == s[i + j - 1])
                {
                    dp[i,i + j - 1] = dp[i + 1,i + j - 2];
                }
            }
        }
    }
  
    // Function to return the number of pairs
    static int countPairs(String s)
    {
  
        // Create the dp table initially
        bool [,]dp = new bool[N,N];
        pre_process(dp, s.ToCharArray());
        int n = s.Length;
  
        // Declare the left array
        int []left = new int[n];
  
        // Declare the right array
        int []right = new int[n];
  
        // Initially left[0] is 1
        left[0] = 1;
  
        // Count the number of palindrome
        // pairs to the left
        for (int i = 1; i < n; i++)
        {
  
            for (int j = 0; j <= i; j++) 
            {
  
                if (dp[j,i] == true)
                {
                    left[i]++;
                }
            }
        }
  
        // Initially right most as 1
        right[n - 1] = 1;
  
        // Count the number of palindrome
        // pairs to the right
        for (int i = n - 2; i >= 0; i--)
        {
  
            right[i] = right[i + 1];
  
            for (int j = n - 1; j >= i; j--)
            {
  
                if (dp[i,j] == true)
                {
                    right[i]++;
                }
            }
        }
  
        int ans = 0;
  
        // Count the number of pairs
        for (int i = 0; i < n - 1; i++)
        {
            ans += left[i] * right[i + 1];
        }
  
        return ans;
    }
  
    // Driver code
    public static void Main(String[] args) 
    {
        String s = "abacaba";
        Console.Write(countPairs(s));
    }
}
  
/* This code contributed by PrinciRaj1992 */


输出:
36