📜  最长重复子序列

📅  最后修改于: 2021-04-23 18:51:52             🧑  作者: Mango

给定一个字符串,找到最长重复子序列的长度,以使两个子序列在相同位置没有相同的字符串字符,即,两个子序列中的任何第i个字符在原始位置都不应具有相同的索引字符串。

最长重复子序列

例子:

Input: str = "abc"
Output: 0
There is no repeating subsequence

Input: str = "aab"
Output: 1
The two subssequence are 'a'(first) and 'a'(second). 
Note that 'b' cannot be considered as part of subsequence 
as it would be at same index in both.

Input: str = "aabb"
Output: 2

Input: str = "axxxy"
Output: 2

这个问题只是最长公共子序列问题的修改。这个想法是找到LCS(str,str),其中str是输入字符串,但要有一个限制,即当两个字符同时,它们不应在两个字符串位于相同的索引上。

以下是该想法的实现。

C++
// C++ program to find the longest repeating
// subsequence
#include 
#include 
using namespace std;
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
int findLongestRepeatingSubSeq(string str)
{
    int n = str.length();
 
    // Create and initialize DP table
    int dp[n+1][n+1];
    for (int i=0; i<=n; i++)
        for (int j=0; j<=n; j++)
            dp[i][j] = 0;
 
    // Fill dp table (similar to LCS loops)
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
        {
            // If characters match and indexes are
            // not same
            if (str[i-1] == str[j-1] && i != j)
                dp[i][j] =  1 + dp[i-1][j-1];         
                      
            // If characters do not match
            else
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
        }
    }
    return dp[n][n];
}
 
// Driver Program
int main()
{
    string str = "aabb";
    cout << "The length of the largest subsequence that"
            " repeats itself is : "
        << findLongestRepeatingSubSeq(str);
    return 0;
}


Java
// Java program to find the longest
// repeating subsequence
import java.io.*;
import java.util.*;
 
class LRS
{
    // Function to find the longest repeating subsequence
    static int findLongestRepeatingSubSeq(String str)
    {
        int n = str.length();
  
        // Create and initialize DP table
        int[][] dp = new int[n+1][n+1];
  
        // Fill dp table (similar to LCS loops)
        for (int i=1; i<=n; i++)
        {
            for (int j=1; j<=n; j++)
            {
                // If characters match and indexes are not same
                if (str.charAt(i-1) == str.charAt(j-1) && i!=j)
                    dp[i][j] =  1 + dp[i-1][j-1];         
                       
                // If characters do not match
                else
                    dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
            }
        }
        return dp[n][n];
    }
     
    // driver program to check above function
    public static void main (String[] args)
    {
        String str = "aabb";
        System.out.println("The length of the largest subsequence that"
            +" repeats itself is : "+findLongestRepeatingSubSeq(str));
    }
}
 
// This code is contributed by Pramod Kumar


Python 3
# Python 3 program to find the longest repeating
# subsequence
 
 
# This function mainly returns LCS(str, str)
# with a condition that same characters at
# same index are not considered.
def findLongestRepeatingSubSeq( str):
 
    n = len(str)
 
    # Create and initialize DP table
    dp=[[0 for i in range(n+1)] for j in range(n+1)]
 
    # Fill dp table (similar to LCS loops)
    for i in range(1,n+1):
        for j in range(1,n+1):
            # If characters match and indexes are
            # not same
            if (str[i-1] == str[j-1] and i != j):
                dp[i][j] = 1 + dp[i-1][j-1]        
                         
            # If characters do not match
            else:
                dp[i][j] = max(dp[i][j-1], dp[i-1][j])
         
     
    return dp[n][n]
 
 
# Driver Program
if __name__=='__main__':
    str = "aabb"
    print("The length of the largest subsequence that repeats itself is : "
          ,findLongestRepeatingSubSeq(str))
 
# this code is contributed by ash264


C#
// C# program to find the longest repeating
// subsequence
using System;
 
class GFG {
     
    // Function to find the longest repeating
    // subsequence
    static int findLongestRepeatingSubSeq(string str)
    {
        int n = str.Length;
 
        // Create and initialize DP table
        int [,]dp = new int[n+1,n+1];
 
        // Fill dp table (similar to LCS loops)
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                 
                // If characters match and indexes
                // are not same
                if (str[i-1] == str[j-1] && i != j)
                    dp[i,j] = 1 + dp[i-1,j-1];        
                         
                // If characters do not match
                else
                    dp[i,j] = Math.Max(dp[i,j-1],
                                       dp[i-1,j]);
            }
        }
        return dp[n,n];
    }
     
    // driver program to check above function
    public static void Main ()
    {
        string str = "aabb";
        Console.Write("The length of the largest "
         + "subsequence that repeats itself is : "
               + findLongestRepeatingSubSeq(str));
    }
}
 
// This code is contributed by nitin mittal.


PHP


Javascript


C++
// C++ program to find the longest repeating
// subsequence using recursion
#include 
using namespace std;
 
int dp[1000][1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
 
int findLongestRepeatingSubSeq(string X, int m, int n)
{
     
    if(dp[m][n]!=-1)
    return dp[m][n];
     
    // return if we have reached the end of either string
    if (m == 0 || n == 0)
        return dp[m][n] = 0;
 
    // if characters at index m and n matches
    // and index is different
    if (X[m - 1] == X[n - 1] && m != n)
        return dp[m][n] = findLongestRepeatingSubSeq(X,
                            m - 1, n - 1) + 1;
 
    // else if characters at index m and n don't match
    return dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1),
                           findLongestRepeatingSubSeq(X, m - 1, n));
}
 
// Longest Repeated Subsequence Problem
int main()
{
    string str = "aabb";
    int m = str.length();
 
memset(dp,-1,sizeof(dp));
cout << "The length of the largest subsequence that"
            " repeats itself is : "
        << findLongestRepeatingSubSeq(str,m,m);
 
    return 0;
// this code is contributed by Kushdeep Mittal
}


Java
import java.util.Arrays;
 
// Java program to find the longest repeating
// subsequence using recursion
public class GFG {
 
    static int dp[][] = new int[1000][1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
    static int findLongestRepeatingSubSeq(char X[], int m, int n) {
 
        if (dp[m][n] != -1) {
            return dp[m][n];
        }
 
        // return if we have reached the end of either string
        if (m == 0 || n == 0) {
            return dp[m][n] = 0;
        }
 
        // if characters at index m and n matches
        // and index is different
        if (X[m - 1] == X[n - 1] && m != n) {
            return dp[m][n] = findLongestRepeatingSubSeq(X,
                    m - 1, n - 1) + 1;
        }
 
        // else if characters at index m and n don't match
        return dp[m][n] = Math.max(findLongestRepeatingSubSeq(X, m, n - 1),
                findLongestRepeatingSubSeq(X, m - 1, n));
    }
 
// Longest Repeated Subsequence Problem
    static public void main(String[] args) {
        String str = "aabb";
        int m = str.length();
        for (int[] row : dp) {
            Arrays.fill(row, -1);
        }
        System.out.println("The length of the largest subsequence that"
                + " repeats itself is : "
                + findLongestRepeatingSubSeq(str.toCharArray(), m, m));
 
    }
}
 
// This code is contributed by 29AjayKumar


Python 3
# Python 3 program to find the longest repeating
# subsequence using recursion
 
dp = [[0 for i in range(1000)] for j in range(1000)]
 
# This function mainly returns LCS(str, str)
# with a condition that same characters at
# same index are not considered.
 
def findLongestRepeatingSubSeq( X, m, n):
     
    if(dp[m][n]!=-1):
        return dp[m][n]
     
    # return if we have reached the end of either string
    if (m == 0 or n == 0):
        dp[m][n] = 0
        return dp[m][n]
 
    # if characters at index m and n matches
    # and index is different
    if (X[m - 1] == X[n - 1] and m != n):
        dp[m][n] = findLongestRepeatingSubSeq(X,
                            m - 1, n - 1) + 1
         
        return dp[m][n]
 
    # else if characters at index m and n don't match
    dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1),
                        findLongestRepeatingSubSeq(X, m - 1, n))
    return dp[m][n]
 
# Longest Repeated Subsequence Problem
if __name__ == "__main__":
    str = "aabb"
    m = len(str)
 
dp =[[-1 for i in range(1000)] for j in range(1000)]
print( "The length of the largest subsequence that"
            " repeats itself is : "
        , findLongestRepeatingSubSeq(str,m,m))
         
# this code is contributed by
# ChitraNayal


C#
//C# program to find the longest repeating
// subsequence using recursion
using System;
public class GFG {
 
    static int [,]dp = new int[1000,1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
    static int findLongestRepeatingSubSeq(char []X, int m, int n) {
 
        if (dp[m,n] != -1) {
            return dp[m,n];
        }
 
        // return if we have reached the end of either string
        if (m == 0 || n == 0) {
            return dp[m,n] = 0;
        }
 
        // if characters at index m and n matches
        // and index is different
        if (X[m - 1] == X[n - 1] && m != n) {
            return dp[m,n] = findLongestRepeatingSubSeq(X,
                    m - 1, n - 1) + 1;
        }
 
        // else if characters at index m and n don't match
        return dp[m,n] = Math.Max(findLongestRepeatingSubSeq(X, m, n - 1),
                findLongestRepeatingSubSeq(X, m - 1, n));
    }
 
// Longest Repeated Subsequence Problem
    static public void Main() {
        String str = "aabb";
        int m = str.Length;
        for (int i = 0; i < dp.GetLength(0); i++)
            for (int j = 0; j < dp.GetLength(1); j++)
                dp[i, j] = -1;
        Console.WriteLine("The length of the largest subsequence that"
                + " repeats itself is : "
                + findLongestRepeatingSubSeq(str.ToCharArray(), m, m));
 
    }
}
 
// This code is contributed by 29AjayKumar


PHP


Java
/*package whatever //do not write package name here */
import java.lang.*;
import java.io.*;
import java.util.*;
 
class GFG
{   
  static int lrs(StringBuilder s1, int i, int j, int[][] dp)
  {
    if(i >= s1.length() || j >= s1.length())
    {
      return 0;
    }
 
    if(dp[i][j] != -1)
    {
      return dp[i][j];
    }
 
    if(dp[i][j] == -1)
    {
      if(s1.charAt(i) == s1.charAt(j) && i != j)
      {
        dp[i][j] = 1 + lrs(s1, i + 1, j + 1, dp);
      }
      else
      {
        dp[i][j] = Math.max(lrs(s1, i, j + 1, dp), lrs(s1, i + 1, j, dp));
      }
    }
    return dp[i][j];
 
  }
 
  // Driver code
  public static void main (String[] args)
  {   
    String s1 = "aabb";  
    StringBuilder input1 = new StringBuilder();
 
    // append a string into StringBuilder input1
    input1.append(s1);
 
    // reverse StringBuilder input1
    input1.reverse();
    int[][] dp = new int[1000][1000];
    for(int[] row : dp)
    {
      Arrays.fill(row, -1);
    }
    System.out.println("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
                       lrs(input1, 0, 0, dp));
  }
}
 
// This code is contributed by rag2127.


Python3
# Python 3 program to find the longest repeating
# subsequence Length
 
# This function mainly returns LRS(str, str,i,j,dp)
# with a condition that same characters at
# same index are not considered.
def lrs(s1, i, j, dp):
   
    # return if we have reached the
    #end of either string
    if i >= len(s1) or j >= len(s1):
        return 0
   
    if dp[i][j] != -1:
        return dp[i][j]
       
    # while dp[i][j] is not computed earlier
    if dp[i][j] == -1:
       
        # if characters at index m and n matches
        # and index is different
        # Index should not match
        if s1[i] == s1[j] and i != j:
            dp[i][j] = 1+lrs(s1, i+1, j+1, dp)
         
        # else if characters at index m and n don't match
        else: 
            dp[i][j] = max(lrs(s1, i, j+1, dp),
                                lrs(s1, i+1, j, dp))
     
    # return answer
    return dp[i][j]
 
# Driver Code
if __name__ == "__main__":
    s1 = "aabb"
     
    # Reversing the same string
    s2 = s1[::-1] 
    dp =[[-1 for i in range(1000)] for j in range(1000)]
    print("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :",
                                    lrs(s1, 0, 0, dp))
     
# this code is contributed by saikumar kudikala


C#
using System;
 
public class GFG{
 
  static int lrs(string s1, int i, int j, int[,] dp)
  {
    if(i >= s1.Length || j >= s1.Length)
    {
      return 0;
    }
 
    if(dp[i, j] != -1)
    {
      return dp[i, j];
    }
 
    if(dp[i, j] == -1)
    {
      if(s1[i] == s1[j] && i != j)
      {
        dp[i, j] = 1 + lrs(s1, i + 1, j + 1, dp);
      }
      else
      {
        dp[i, j] = Math.Max(lrs(s1, i, j + 1, dp), lrs(s1, i + 1, j, dp));
      }
    }
    return dp[i, j];
 
  }
 
  // Driver code
  static public void Main (){
    string s1 = "aabb";
    char[] chars = s1.ToCharArray();
    Array.Reverse(chars);
    s1= new String(chars);
 
    int[,] dp = new int[1000,1000];
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        dp[i, j] = -1;
      }
    }
    Console.WriteLine("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
                      lrs(s1, 0, 0, dp));
  }
}
 
// This code is contributed by avanitrachhadiya2155


输出:

The length of the largest subsequence that repeats itself is : 2

另一种方法:(使用递归)

C++

// C++ program to find the longest repeating
// subsequence using recursion
#include 
using namespace std;
 
int dp[1000][1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
 
int findLongestRepeatingSubSeq(string X, int m, int n)
{
     
    if(dp[m][n]!=-1)
    return dp[m][n];
     
    // return if we have reached the end of either string
    if (m == 0 || n == 0)
        return dp[m][n] = 0;
 
    // if characters at index m and n matches
    // and index is different
    if (X[m - 1] == X[n - 1] && m != n)
        return dp[m][n] = findLongestRepeatingSubSeq(X,
                            m - 1, n - 1) + 1;
 
    // else if characters at index m and n don't match
    return dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1),
                           findLongestRepeatingSubSeq(X, m - 1, n));
}
 
// Longest Repeated Subsequence Problem
int main()
{
    string str = "aabb";
    int m = str.length();
 
memset(dp,-1,sizeof(dp));
cout << "The length of the largest subsequence that"
            " repeats itself is : "
        << findLongestRepeatingSubSeq(str,m,m);
 
    return 0;
// this code is contributed by Kushdeep Mittal
}

Java

import java.util.Arrays;
 
// Java program to find the longest repeating
// subsequence using recursion
public class GFG {
 
    static int dp[][] = new int[1000][1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
    static int findLongestRepeatingSubSeq(char X[], int m, int n) {
 
        if (dp[m][n] != -1) {
            return dp[m][n];
        }
 
        // return if we have reached the end of either string
        if (m == 0 || n == 0) {
            return dp[m][n] = 0;
        }
 
        // if characters at index m and n matches
        // and index is different
        if (X[m - 1] == X[n - 1] && m != n) {
            return dp[m][n] = findLongestRepeatingSubSeq(X,
                    m - 1, n - 1) + 1;
        }
 
        // else if characters at index m and n don't match
        return dp[m][n] = Math.max(findLongestRepeatingSubSeq(X, m, n - 1),
                findLongestRepeatingSubSeq(X, m - 1, n));
    }
 
// Longest Repeated Subsequence Problem
    static public void main(String[] args) {
        String str = "aabb";
        int m = str.length();
        for (int[] row : dp) {
            Arrays.fill(row, -1);
        }
        System.out.println("The length of the largest subsequence that"
                + " repeats itself is : "
                + findLongestRepeatingSubSeq(str.toCharArray(), m, m));
 
    }
}
 
// This code is contributed by 29AjayKumar

的Python 3

# Python 3 program to find the longest repeating
# subsequence using recursion
 
dp = [[0 for i in range(1000)] for j in range(1000)]
 
# This function mainly returns LCS(str, str)
# with a condition that same characters at
# same index are not considered.
 
def findLongestRepeatingSubSeq( X, m, n):
     
    if(dp[m][n]!=-1):
        return dp[m][n]
     
    # return if we have reached the end of either string
    if (m == 0 or n == 0):
        dp[m][n] = 0
        return dp[m][n]
 
    # if characters at index m and n matches
    # and index is different
    if (X[m - 1] == X[n - 1] and m != n):
        dp[m][n] = findLongestRepeatingSubSeq(X,
                            m - 1, n - 1) + 1
         
        return dp[m][n]
 
    # else if characters at index m and n don't match
    dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1),
                        findLongestRepeatingSubSeq(X, m - 1, n))
    return dp[m][n]
 
# Longest Repeated Subsequence Problem
if __name__ == "__main__":
    str = "aabb"
    m = len(str)
 
dp =[[-1 for i in range(1000)] for j in range(1000)]
print( "The length of the largest subsequence that"
            " repeats itself is : "
        , findLongestRepeatingSubSeq(str,m,m))
         
# this code is contributed by
# ChitraNayal

C#

//C# program to find the longest repeating
// subsequence using recursion
using System;
public class GFG {
 
    static int [,]dp = new int[1000,1000];
 
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
    static int findLongestRepeatingSubSeq(char []X, int m, int n) {
 
        if (dp[m,n] != -1) {
            return dp[m,n];
        }
 
        // return if we have reached the end of either string
        if (m == 0 || n == 0) {
            return dp[m,n] = 0;
        }
 
        // if characters at index m and n matches
        // and index is different
        if (X[m - 1] == X[n - 1] && m != n) {
            return dp[m,n] = findLongestRepeatingSubSeq(X,
                    m - 1, n - 1) + 1;
        }
 
        // else if characters at index m and n don't match
        return dp[m,n] = Math.Max(findLongestRepeatingSubSeq(X, m, n - 1),
                findLongestRepeatingSubSeq(X, m - 1, n));
    }
 
// Longest Repeated Subsequence Problem
    static public void Main() {
        String str = "aabb";
        int m = str.Length;
        for (int i = 0; i < dp.GetLength(0); i++)
            for (int j = 0; j < dp.GetLength(1); j++)
                dp[i, j] = -1;
        Console.WriteLine("The length of the largest subsequence that"
                + " repeats itself is : "
                + findLongestRepeatingSubSeq(str.ToCharArray(), m, m));
 
    }
}
 
// This code is contributed by 29AjayKumar

的PHP


输出:

The length of the largest subsequence that repeats itself is : 2

方法3:

要找到最长重复子序列动态编程自顶向下方法的长度,请执行以下操作:

  • 接受输入字符串。
  • 执行最长公共子序列,其中s1 [i] == s1 [j]和i!= j。
  • 返回长度。

Java

/*package whatever //do not write package name here */
import java.lang.*;
import java.io.*;
import java.util.*;
 
class GFG
{   
  static int lrs(StringBuilder s1, int i, int j, int[][] dp)
  {
    if(i >= s1.length() || j >= s1.length())
    {
      return 0;
    }
 
    if(dp[i][j] != -1)
    {
      return dp[i][j];
    }
 
    if(dp[i][j] == -1)
    {
      if(s1.charAt(i) == s1.charAt(j) && i != j)
      {
        dp[i][j] = 1 + lrs(s1, i + 1, j + 1, dp);
      }
      else
      {
        dp[i][j] = Math.max(lrs(s1, i, j + 1, dp), lrs(s1, i + 1, j, dp));
      }
    }
    return dp[i][j];
 
  }
 
  // Driver code
  public static void main (String[] args)
  {   
    String s1 = "aabb";  
    StringBuilder input1 = new StringBuilder();
 
    // append a string into StringBuilder input1
    input1.append(s1);
 
    // reverse StringBuilder input1
    input1.reverse();
    int[][] dp = new int[1000][1000];
    for(int[] row : dp)
    {
      Arrays.fill(row, -1);
    }
    System.out.println("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
                       lrs(input1, 0, 0, dp));
  }
}
 
// This code is contributed by rag2127.

Python3

# Python 3 program to find the longest repeating
# subsequence Length
 
# This function mainly returns LRS(str, str,i,j,dp)
# with a condition that same characters at
# same index are not considered.
def lrs(s1, i, j, dp):
   
    # return if we have reached the
    #end of either string
    if i >= len(s1) or j >= len(s1):
        return 0
   
    if dp[i][j] != -1:
        return dp[i][j]
       
    # while dp[i][j] is not computed earlier
    if dp[i][j] == -1:
       
        # if characters at index m and n matches
        # and index is different
        # Index should not match
        if s1[i] == s1[j] and i != j:
            dp[i][j] = 1+lrs(s1, i+1, j+1, dp)
         
        # else if characters at index m and n don't match
        else: 
            dp[i][j] = max(lrs(s1, i, j+1, dp),
                                lrs(s1, i+1, j, dp))
     
    # return answer
    return dp[i][j]
 
# Driver Code
if __name__ == "__main__":
    s1 = "aabb"
     
    # Reversing the same string
    s2 = s1[::-1] 
    dp =[[-1 for i in range(1000)] for j in range(1000)]
    print("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :",
                                    lrs(s1, 0, 0, dp))
     
# this code is contributed by saikumar kudikala

C#

using System;
 
public class GFG{
 
  static int lrs(string s1, int i, int j, int[,] dp)
  {
    if(i >= s1.Length || j >= s1.Length)
    {
      return 0;
    }
 
    if(dp[i, j] != -1)
    {
      return dp[i, j];
    }
 
    if(dp[i, j] == -1)
    {
      if(s1[i] == s1[j] && i != j)
      {
        dp[i, j] = 1 + lrs(s1, i + 1, j + 1, dp);
      }
      else
      {
        dp[i, j] = Math.Max(lrs(s1, i, j + 1, dp), lrs(s1, i + 1, j, dp));
      }
    }
    return dp[i, j];
 
  }
 
  // Driver code
  static public void Main (){
    string s1 = "aabb";
    char[] chars = s1.ToCharArray();
    Array.Reverse(chars);
    s1= new String(chars);
 
    int[,] dp = new int[1000,1000];
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        dp[i, j] = -1;
      }
    }
    Console.WriteLine("LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
                      lrs(s1, 0, 0, dp));
  }
}
 
// This code is contributed by avanitrachhadiya2155
输出
LENGTH OF LONGEST REPEATING SUBSEQUENCE IS : 2