📌  相关文章
📜  查找给定字符串的所有不同回文子字符串

📅  最后修改于: 2021-09-17 07:34:19             🧑  作者: Mango

给定字符串小写 ASCII字符,找出它所有不同的连续回文子串。

例子:

Input: str = "abaaa"
Output:  Below are 5 palindrome sub-strings
a
aa
aaa
aba
b


Input: str = "geek"
Output:  Below are 4 palindrome sub-strings
e
ee
g
k

步骤 1:使用修改后的 Manacher 算法查找所有回文:
将每个字符视为一个支点,在两侧展开以找到以所考虑的支点字符为中心的偶数和奇数长度回文的长度,并将长度存储在 2 个数组中(奇数和偶数)。
这一步的时间复杂度是 O(n^2)

第 2 步:将所有找到的回文插入 HashMap:
将上一步找到的所有回文插入到一个 HashMap 中。还将字符串的所有单个字符插入 HashMap(以生成不同的单字母回文子字符串)。
这一步的时间复杂度是 O(n^3) 假设哈希插入搜索需要 O(1) 时间。请注意,一个字符串最多可以有 O(n^2) 个回文子串。在下面的 C++ 代码中,使用了有序的 hashmap,其中插入和搜索的时间复杂度为 O(Logn)。在 C++ 中,有序的 hashmap 是使用红黑树实现的。

第 3 步:打印不同的回文数和这些不同的回文数:
最后一步是打印存储在 HashMap 中的所有值(由于 HashMap 的属性,只会对不同的元素进行哈希处理)。地图的大小给出了不同的回文连续子串的数量。

下面是上述想法的实现。

C/C++
// C++ program to find all distinct palindrome sub-strings
// of a given string
#include 
#include 
using namespace std;
  
// Function to print all distinct palindrome sub-strings of s
void palindromeSubStrs(string s)
{
    map m;
    int n = s.size();
  
    // table for storing results (2 rows for odd-
    // and even-length palindromes
    int R[2][n+1];
  
    // Find all sub-string palindromes from the given input
    // string insert 'guards' to iterate easily over s
    s = "@" + s + "#";
  
    for (int j = 0; j <= 1; j++)
    {
        int rp = 0;   // length of 'palindrome radius'
        R[j][0] = 0;
  
        int i = 1;
        while (i <= n)
        {
            //  Attempt to expand palindrome centered at i
            while (s[i - rp - 1] == s[i + j + rp])
                rp++;  // Incrementing the length of palindromic
                       // radius as and when we find vaid palindrome
  
            // Assigning the found palindromic length to odd/even
            // length array
            R[j][i] = rp;
            int k = 1;
            while ((R[j][i - k] != rp - k) && (k < rp))
            {
                R[j][i + k] = min(R[j][i - k],rp - k);
                k++;
            }
            rp = max(rp - k,0);
            i += k;
        }
    }
  
    // remove 'guards'
    s = s.substr(1, n);
  
    // Put all obtained palindromes in a hash map to
    // find only distinct palindromess
    m[string(1, s[0])]=1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= 1; j++)
            for (int rp = R[j][i]; rp > 0; rp--)
               m[s.substr(i - rp - 1, 2 * rp + j)]=1;
        m[string(1, s[i])]=1;
    }
  
    //printing all distinct palindromes from hash map
   cout << "Below are " << m.size()-1
        << " palindrome sub-strings";
   map::iterator ii;
   for (ii = m.begin(); ii!=m.end(); ++ii)
      cout << (*ii).first << endl;
}
  
// Driver program
int main()
{
    palindromeSubStrs("abaaa");
    return 0;
}


Java
// Java program to find all distinct palindrome
// sub-strings of a given string
import java.util.Map;
import java.util.TreeMap;
  
public class GFG 
{     
    // Function to print all distinct palindrome
    // sub-strings of s
    static void palindromeSubStrs(String s)
    {
        //map m;
        TreeMap m = new TreeMap<>();
        int n = s.length();
       
        // table for storing results (2 rows for odd-
        // and even-length palindromes
        int[][] R = new int[2][n+1];
       
        // Find all sub-string palindromes from the 
        // given input string insert 'guards' to 
        // iterate easily over s
        s = "@" + s + "#";
       
        for (int j = 0; j <= 1; j++)
        {
            int rp = 0;   // length of 'palindrome radius'
            R[j][0] = 0;
       
            int i = 1;
            while (i <= n)
            {
                //  Attempt to expand palindrome centered 
                // at i
                while (s.charAt(i - rp - 1) == s.charAt(i + 
                                                j + rp))
                    rp++;  // Incrementing the length of
                           // palindromic radius as and 
                           // when we find vaid palindrome
       
                // Assigning the found palindromic length
                // to odd/even length array
                R[j][i] = rp;
                int k = 1;
                while ((R[j][i - k] != rp - k) && (k < rp))
                {
                    R[j][i + k] = Math.min(R[j][i - k], 
                                              rp - k);
                    k++;
                }
                rp = Math.max(rp - k,0);
                i += k;
            }
        }
       
        // remove 'guards'
        s = s.substring(1, s.length()-1);
       
        // Put all obtained palindromes in a hash map to
        // find only distinct palindromess
        m.put(s.substring(0,1), 1);
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j <= 1; j++)
                for (int rp = R[j][i]; rp > 0; rp--)
                   m.put(s.substring(i - rp - 1,  i - rp - 1 
                                       + 2 * rp + j), 1);
            m.put(s.substring(i, i + 1), 1);
        }
       
        // printing all distinct palindromes from 
        // hash map
       System.out.println("Below are " + (m.size())
                           + " palindrome sub-strings");
         
       for (Map.Entry ii:m.entrySet())
          System.out.println(ii.getKey());
    }
       
    // Driver program
    public static void main(String args[])
    {
        palindromeSubStrs("abaaa");
    }
}
// This code is contributed by Sumit Ghosh


Python
# Python program Find all distinct palindromic sub-strings
# of a given string
  
# Function to print all distinct palindrome sub-strings of s
def palindromeSubStrs(s):
    m = dict()
    n = len(s)
  
    # table for storing results (2 rows for odd-
    # and even-length palindromes
    R = [[0 for x in xrange(n+1)] for x in xrange(2)]
  
    # Find all sub-string palindromes from the given input
    # string insert 'guards' to iterate easily over s
    s = "@" + s + "#"
  
    for j in xrange(2):
        rp = 0    # length of 'palindrome radius'
        R[j][0] = 0
  
        i = 1
        while i <= n:
  
            # Attempt to expand palindrome centered at i
            while s[i - rp - 1] == s[i + j + rp]:
                rp += 1 # Incrementing the length of palindromic
                        # radius as and when we find valid palindrome
  
            # Assigning the found palindromic length to odd/even
            # length array
            R[j][i] = rp
            k = 1
            while (R[j][i - k] != rp - k) and (k < rp):
                R[j][i+k] = min(R[j][i-k], rp - k)
                k += 1
            rp = max(rp - k, 0)
            i += k
  
    # remove guards
    s = s[1:len(s)-1]
  
    # Put all obtained palindromes in a hash map to
    # find only distinct palindrome
    m[s[0]] = 1
    for i in xrange(1,n):
        for j in xrange(2):
            for rp in xrange(R[j][i],0,-1):
                m[s[i - rp - 1 : i - rp - 1 + 2 * rp + j]] = 1
        m[s[i]] = 1
  
    # printing all distinct palindromes from hash map
    print "Below are " + str(len(m)) + " pali sub-strings"
    for i in m:
        print i
  
# Driver program
palindromeSubStrs("abaaa")
# This code is contributed by BHAVYA JAIN and ROHIT SIKKA


C#
// C# program to find all distinct palindrome 
// sub-strings of a given string
using System;
using System.Collections.Generic;
  
class GFG 
{
  
    // Function to print all distinct palindrome 
    // sub-strings of s
    public static void palindromeSubStrs(string s) 
    {
        //map m;
        Dictionary < string,
        int > m = new Dictionary < string,
        int > ();
        int n = s.Length;
  
        // table for storing results (2 rows for odd- 
        // and even-length palindromes
        int[, ] R = new int[2, n + 1];
  
        // Find all sub-string palindromes from the 
        // given input string insert 'guards' to 
        // iterate easily over s
        s = "@" + s + "#";
        for (int j = 0; j <= 1; j++)
        {
            int rp = 0; // length of 'palindrome radius'
            R[j, 0] = 0;
            int i = 1;
            while (i <= n) 
            {
                  
                // Attempt to expand palindrome centered 
                // at i
                while (s[i - rp - 1] == s[i + j + rp])
  
                // Incrementing the length of 
                // palindromic radius as and 
                // when we find vaid palindrome
                rp++;
  
                // Assigning the found palindromic length 
                // to odd/even length array
                R[j, i] = rp;
                int k = 1;
                while ((R[j, i - k] != rp - k) && k < rp)
                {
                    R[j, i + k] = Math.Min(R[j, i - k], rp - k);
                    k++;
                }
                rp = Math.Max(rp - k, 0);
                i += k;
            }
        }
  
        // remove 'guards'
        s = s.Substring(1);
  
        // Put all obtained palindromes in a hash map to 
        // find only distinct palindromess
        if (!m.ContainsKey(s.Substring(0, 1))) 
            m.Add(s.Substring(0, 1), 1);
        else 
            m[s.Substring(0, 1)]++;
  
        for (int i = 1; i < n; i++) 
        {
            for (int j = 0; j <= 1; j++)
            for (int rp = R[j, i]; rp > 0; rp--) 
            {
                if (!m.ContainsKey(s.Substring(i - rp - 1, 2 * rp + j))) 
                    m.Add(s.Substring(i - rp - 1, 2 * rp + j), 1);
                else
                    m[s.Substring(i - rp - 1, 2 * rp + j)]++;
            }
  
            if (!m.ContainsKey(s.Substring(i, 1))) 
                m.Add(s.Substring(i, 1), 1);
            else
                m[s.Substring(i, 1)]++;
        }
  
        // printing all distinct palindromes from 
        // hash map
        Console.WriteLine("Below are " + (m.Count));
  
        foreach(KeyValuePair < string, int > ii in m)
        Console.WriteLine(ii.Key);
    }
  
    // Driver Code
    public static void Main(string[] args) 
    {
        palindromeSubStrs("abaaa");
    }
}
  
// This code is contributed by
// sanjeev2552


输出:

Below are 5 palindrome sub-strings
a
aa
aaa
aba
b 

类似问题:
计算一个字符串中的所有回文子字符串

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程