Печат на най -дългата често срещана последователност | Комплект 2 (отпечатване на всички)

Като се има предвид две последователности, отпечатват всички най -дълги последствия, присъстващи и в двете.
Примери:  
 

  Input:    string X = 'AGTGATG' string Y = 'GTTAG'   Output:    GTAG GTTG   Input:    string X = 'AATCC' string Y = 'ACACG'   Output:    ACC AAC   Input:    string X = 'ABCBDAB' string Y = 'BDCABA'   Output:    BCAB BCBA BDAB 


 


Обсъждахме проблема с най -дългата честота (LCS) тук . Функцията, обсъдена там, беше главно за намиране на дължината на LCS. Обсъждахме и как да отпечатаме най -дългата последователност тук . Но тъй като LCS за два струни не е уникален в тази публикация, ние ще разпечатаме всички възможни решения на проблема с LCS.
Следва подробен алгоритъм за отпечатване на всички LC.
Конструираме l [m+1] [n+1] таблица, както е обсъдено в предишен Публикувайте и преминете 2D масива, започващ от L [M] [n]. За текущата клетка l [i] [j] в матрицата
а) Ако последните знаци на x и y са еднакви (т.е. x [i-1] == y [j-1]), символът трябва да присъства във всички LCs на подреда x [0 ... I-1] и y [0..J-1]. Ние просто се повтаряме за L [I-1] [J-1] в матрицата и добавяме токов характер на всички LC, възможни на подстриране x [0 ... I-2] и y [0..J-2].
б) Ако последните знаци на x и y не са еднакви (т.е. x [i-1]! = y [j-1]), тогава LC могат да бъдат конструирани от горната страна на матрицата (т.е. l [i-1] [j]) или от лявата страна на матрицата (т.е. l [i] [j-1]) в зависимост от това, от което стойността е по-голяма. Ако и двете стойности са равни (т.е. l [i-1] [j] == l [i] [j-1]), тогава тя ще бъде конструирана от двете страни на матрицата. Така че въз основа на стойности при l [i-1] [j] и l [i] [j-1] вървим в посока с по-голяма стойност или отиваме в двете посоки, ако стойностите са равни.
По -долу е рекурсивно прилагане на горната идея - 
 

C++
   /* Dynamic Programming implementation of LCS problem */   #include          using     namespace     std  ;   // Maximum string length   #define N 100   int     L  [  N  ][  N  ];   /* Returns set containing all LCS for X[0..m-1] Y[0..n-1] */   set   <  string  >     findLCS  (  string     X       string     Y       int     m       int     n  )   {      // construct a set to store possible LCS      set   <  string  >     s  ;      // If we reaches end of either string return      // a empty set      if     (  m     ==     0     ||     n     ==     0  )      {      s  .  insert  (  ''  );      return     s  ;      }      // If the last characters of X and Y are same      if     (  X  [  m     -     1  ]     ==     Y  [  n     -     1  ])      {      // recurse for X[0..m-2] and Y[0..n-2] in      // the matrix      set   <  string  >     tmp     =     findLCS  (  X       Y       m     -     1       n     -     1  );      // append current character to all possible LCS      // of substring X[0..m-2] and Y[0..n-2].      for     (  string     str     :     tmp  )      s  .  insert  (  str     +     X  [  m     -     1  ]);      }      // If the last characters of X and Y are not same      else      {      // If LCS can be constructed from top side of      // the matrix recurse for X[0..m-2] and Y[0..n-1]      if     (  L  [  m     -     1  ][  n  ]     >=     L  [  m  ][  n     -     1  ])      s     =     findLCS  (  X       Y       m     -     1       n  );      // If LCS can be constructed from left side of      // the matrix recurse for X[0..m-1] and Y[0..n-2]      if     (  L  [  m  ][  n     -     1  ]     >=     L  [  m     -     1  ][  n  ])      {      set   <  string  >     tmp     =     findLCS  (  X       Y       m       n     -     1  );      // merge two sets if L[m-1][n] == L[m][n-1]      // Note s will be empty if L[m-1][n] != L[m][n-1]      s  .  insert  (  tmp  .  begin  ()     tmp  .  end  ());      }      }      return     s  ;   }   /* Returns length of LCS for X[0..m-1] Y[0..n-1] */   int     LCS  (  string     X       string     Y       int     m       int     n  )   {      // Build L[m+1][n+1] in bottom up fashion      for     (  int     i     =     0  ;     i      <=     m  ;     i  ++  )      {      for     (  int     j     =     0  ;     j      <=     n  ;     j  ++  )      {      if     (  i     ==     0     ||     j     ==     0  )      L  [  i  ][  j  ]     =     0  ;      else     if     (  X  [  i     -     1  ]     ==     Y  [  j     -     1  ])      L  [  i  ][  j  ]     =     L  [  i     -     1  ][  j     -     1  ]     +     1  ;      else      L  [  i  ][  j  ]     =     max  (  L  [  i     -     1  ][  j  ]     L  [  i  ][  j     -     1  ]);      }      }      return     L  [  m  ][  n  ];   }   /* Driver program to test above function */   int     main  ()   {      string     X     =     'AGTGATG'  ;      string     Y     =     'GTTAG'  ;      int     m     =     X  .  length  ();      int     n     =     Y  .  length  ();      cout      < <     'LCS length is '      < <     LCS  (  X       Y       m       n  )      < <     endl  ;      set   <  string  >     s     =     findLCS  (  X       Y       m       n  );      for     (  string     str     :     s  )      cout      < <     str      < <     endl  ;      return     0  ;   }   
Java
   /* Dynamic Programming implementation of LCS problem */   import     java.util.*  ;   class   GFG   {   // Maximum String length   static     int     N     =     100  ;   static     int     [][]  L     =     new     int  [  N  ][  N  ]  ;   /* Returns set containing all LCS for     X[0..m-1] Y[0..n-1] */   static     Set   <  String  >     findLCS  (  String     X           String     Y       int     m       int     n  )   {      // construct a set to store possible LCS      Set   <  String  >     s     =     new     HashSet   <>  ();      // If we reaches end of either String       // return a empty set      if     (  m     ==     0     ||     n     ==     0  )      {      s  .  add  (  ''  );      return     s  ;      }      // If the last characters of X and Y are same      if     (  X  .  charAt  (  m     -     1  )     ==     Y  .  charAt  (  n     -     1  ))      {      // recurse for X[0..m-2] and Y[0..n-2]       // in the matrix      Set   <  String  >     tmp     =     findLCS  (  X       Y       m     -     1       n     -     1  );      // append current character to all possible LCS      // of subString X[0..m-2] and Y[0..n-2].      for     (  String     str     :     tmp  )      s  .  add  (  str     +     X  .  charAt  (  m     -     1  ));      }      // If the last characters of X and Y are not same      else      {      // If LCS can be constructed from top side of      // the matrix recurse for X[0..m-2] and Y[0..n-1]      if     (  L  [  m     -     1  ][  n  ]     >=     L  [  m  ][  n     -     1  ]  )      s     =     findLCS  (  X       Y       m     -     1       n  );      // If LCS can be constructed from left side of      // the matrix recurse for X[0..m-1] and Y[0..n-2]      if     (  L  [  m  ][  n     -     1  ]     >=     L  [  m     -     1  ][  n  ]  )      {      Set   <  String  >     tmp     =     findLCS  (  X       Y       m       n     -     1  );      // merge two sets if L[m-1][n] == L[m][n-1]      // Note s will be empty if L[m-1][n] != L[m][n-1]      s  .  addAll  (  tmp  );      }      }      return     s  ;   }   /* Returns length of LCS for X[0..m-1] Y[0..n-1] */   static     int     LCS  (  String     X       String     Y       int     m       int     n  )   {      // Build L[m+1][n+1] in bottom up fashion      for     (  int     i     =     0  ;     i      <=     m  ;     i  ++  )      {      for     (  int     j     =     0  ;     j      <=     n  ;     j  ++  )      {      if     (  i     ==     0     ||     j     ==     0  )      L  [  i  ][  j  ]     =     0  ;      else     if     (  X  .  charAt  (  i     -     1  )     ==     Y  .  charAt  (  j     -     1  ))      L  [  i  ][  j  ]     =     L  [  i     -     1  ][  j     -     1  ]     +     1  ;      else      L  [  i  ][  j  ]     =     Math  .  max  (  L  [  i     -     1  ][  j  ]        L  [  i  ][  j     -     1  ]  );      }      }      return     L  [  m  ][  n  ]  ;   }   // Driver Code   public     static     void     main  (  String  []     args  )   {      String     X     =     'AGTGATG'  ;      String     Y     =     'GTTAG'  ;      int     m     =     X  .  length  ();      int     n     =     Y  .  length  ();      System  .  out  .  println  (  'LCS length is '     +      LCS  (  X       Y       m       n  ));      Set   <  String  >     s     =     findLCS  (  X       Y       m       n  );      for     (  String     str     :     s  )      System  .  out  .  println  (  str  );   }   }   // This code is contributed by 29AjayKumar   
Python3
   # Dynamic Programming implementation of LCS problem   # Maximum string length   N   =   100   L   =   [[  0   for   i   in   range  (  N  )]   for   j   in   range  (  N  )]   # Returns set containing all LCS    # for X[0..m-1] Y[0..n-1]   def   findLCS  (  x     y     m     n  ):   # construct a set to store possible LCS   s   =   set  ()   # If we reaches end of either string return   # a empty set   if   m   ==   0   or   n   ==   0  :   s  .  add  (  ''  )   return   s   # If the last characters of X and Y are same   if   x  [  m   -   1  ]   ==   y  [  n   -   1  ]:   # recurse for X[0..m-2] and Y[0..n-2] in   # the matrix   tmp   =   findLCS  (  x     y     m   -   1     n   -   1  )   # append current character to all possible LCS   # of substring X[0..m-2] and Y[0..n-2].   for   string   in   tmp  :   s  .  add  (  string   +   x  [  m   -   1  ])   # If the last characters of X and Y are not same   else  :   # If LCS can be constructed from top side of   # the matrix recurse for X[0..m-2] and Y[0..n-1]   if   L  [  m   -   1  ][  n  ]   >=   L  [  m  ][  n   -   1  ]:   s   =   findLCS  (  x     y     m   -   1     n  )   # If LCS can be constructed from left side of   # the matrix recurse for X[0..m-1] and Y[0..n-2]   if   L  [  m  ][  n   -   1  ]   >=   L  [  m   -   1  ][  n  ]:   tmp   =   findLCS  (  x     y     m     n   -   1  )   # merge two sets if L[m-1][n] == L[m][n-1]   # Note s will be empty if L[m-1][n] != L[m][n-1]   for   i   in   tmp  :   s  .  add  (  i  )   return   s   # Returns length of LCS for X[0..m-1] Y[0..n-1]   def   LCS  (  x     y     m     n  ):   # Build L[m+1][n+1] in bottom up fashion   for   i   in   range  (  m   +   1  ):   for   j   in   range  (  n   +   1  ):   if   i   ==   0   or   j   ==   0  :   L  [  i  ][  j  ]   =   0   else   if   x  [  i   -   1  ]   ==   y  [  j   -   1  ]:   L  [  i  ][  j  ]   =   L  [  i   -   1  ][  j   -   1  ]   +   1   else  :   L  [  i  ][  j  ]   =   max  (  L  [  i   -   1  ][  j  ]   L  [  i  ][  j   -   1  ])   return   L  [  m  ][  n  ]   # Driver Code   if   __name__   ==   '__main__'  :   x   =   'AGTGATG'   y   =   'GTTAG'   m   =   len  (  x  )   n   =   len  (  y  )   print  (  'LCS length is'     LCS  (  x     y     m     n  ))   s   =   findLCS  (  x     y     m     n  )   for   i   in   s  :   print  (  i  )   # This code is contributed by   # sanjeev2552   
C#
   // Dynamic Programming implementation    // of LCS problem    using     System  ;   using     System.Collections.Generic  ;          class     GFG   {   // Maximum String length   static     int     N     =     100  ;   static     int     []  L     =     new     int  [  N       N  ];   /* Returns set containing all LCS for    X[0..m-1] Y[0..n-1] */   static     HashSet   <  String  >     findLCS  (  String     X           String     Y        int     m       int     n  )   {      // construct a set to store possible LCS      HashSet   <  String  >     s     =     new     HashSet   <  String  >  ();      // If we reaches end of either String       // return a empty set      if     (  m     ==     0     ||     n     ==     0  )      {      s  .  Add  (  ''  );      return     s  ;      }      // If the last characters of X and Y are same      if     (  X  [  m     -     1  ]     ==     Y  [  n     -     1  ])      {      // recurse for X[0..m-2] and Y[0..n-2]       // in the matrix      HashSet   <  String  >     tmp     =     findLCS  (  X       Y       m     -     1       n     -     1  );      // append current character to all possible LCS      // of subString X[0..m-2] and Y[0..n-2].      foreach     (  String     str     in     tmp  )      s  .  Add  (  str     +     X  [  m     -     1  ]);      }      // If the last characters of X and Y are not same      else      {      // If LCS can be constructed from top side of      // the matrix recurse for X[0..m-2] and Y[0..n-1]      if     (  L  [  m     -     1       n  ]     >=     L  [  m       n     -     1  ])      s     =     findLCS  (  X       Y       m     -     1       n  );      // If LCS can be constructed from left side of      // the matrix recurse for X[0..m-1] and Y[0..n-2]      if     (  L  [  m       n     -     1  ]     >=     L  [  m     -     1       n  ])      {      HashSet   <  String  >     tmp     =     findLCS  (  X       Y       m       n     -     1  );      // merge two sets if L[m-1n] == L[mn-1]      // Note s will be empty if L[m-1n] != L[mn-1]      foreach     (  String     str     in     tmp  )      s  .  Add  (  str  );      }      }      return     s  ;   }   /* Returns length of LCS for X[0..m-1] Y[0..n-1] */   static     int     LCS  (  String     X       String     Y       int     m       int     n  )   {      // Build L[m+1n+1] in bottom up fashion      for     (  int     i     =     0  ;     i      <=     m  ;     i  ++  )      {      for     (  int     j     =     0  ;     j      <=     n  ;     j  ++  )      {      if     (  i     ==     0     ||     j     ==     0  )      L  [  i       j  ]     =     0  ;      else     if     (  X  [  i     -     1  ]     ==     Y  [  j     -     1  ])      L  [  i       j  ]     =     L  [  i     -     1       j     -     1  ]     +     1  ;      else      L  [  i       j  ]     =     Math  .  Max  (  L  [  i     -     1       j  ]      L  [  i       j     -     1  ]);      }      }      return     L  [  m       n  ];   }   // Driver Code   public     static     void     Main  (  String  []     args  )   {      String     X     =     'AGTGATG'  ;      String     Y     =     'GTTAG'  ;      int     m     =     X  .  Length  ;      int     n     =     Y  .  Length  ;      Console  .  WriteLine  (  'LCS length is '     +      LCS  (  X       Y       m       n  ));      HashSet   <  String  >     s     =     findLCS  (  X       Y       m       n  );      foreach     (  String     str     in     s  )      Console  .  WriteLine  (  str  );   }   }       // This code is contributed by Rajput-Ji   
JavaScript
    <  script  >   /* Dynamic Programming implementation of LCS problem */   // Maximum String length   let     N     =     100  ;   let     L     =     new     Array  (  N  );   for  (  let     i  =  0  ;  i   <  N  ;  i  ++  )   {      L  [  i  ]  =  new     Array  (  N  );       }   /* Returns set containing all LCS for     X[0..m-1] Y[0..n-1] */   function     findLCS  (  X    Y    m    n  )   {      // construct a set to store possible LCS      let     s     =     new     Set  ();          // If we reaches end of either String       // return a empty set      if     (  m     ==     0     ||     n     ==     0  )      {      s  .  add  (  ''  );      return     s  ;      }          // If the last characters of X and Y are same      if     (  X  [  m  -  1  ]     ==     Y  [  n  -  1  ])      {      // recurse for X[0..m-2] and Y[0..n-2]       // in the matrix      let     tmp     =     findLCS  (  X       Y       m     -     1       n     -     1  );          // append current character to all possible LCS      // of subString X[0..m-2] and Y[0..n-2].      for     (  let     str     of     tmp  .  values  ())      s  .  add  (  str     +     X  [  m  -  1  ]);      }          // If the last characters of X and Y are not same      else      {      // If LCS can be constructed from top side of      // the matrix recurse for X[0..m-2] and Y[0..n-1]      if     (  L  [  m     -     1  ][  n  ]     >=     L  [  m  ][  n     -     1  ])      s     =     findLCS  (  X       Y       m     -     1       n  );          // If LCS can be constructed from left side of      // the matrix recurse for X[0..m-1] and Y[0..n-2]      if     (  L  [  m  ][  n     -     1  ]     >=     L  [  m     -     1  ][  n  ])      {      let     tmp     =     findLCS  (  X       Y       m       n     -     1  );          // merge two sets if L[m-1][n] == L[m][n-1]      // Note s will be empty if L[m-1][n] != L[m][n-1]          for     (  let     item     of     tmp  .  values  ())      s  .  add  (  item  )      }      }      return     s  ;   }   /* Returns length of LCS for X[0..m-1] Y[0..n-1] */   function     LCS  (  X    Y    m    n  )   {      // Build L[m+1][n+1] in bottom up fashion      for     (  let     i     =     0  ;     i      <=     m  ;     i  ++  )      {      for     (  let     j     =     0  ;     j      <=     n  ;     j  ++  )      {      if     (  i     ==     0     ||     j     ==     0  )      L  [  i  ][  j  ]     =     0  ;      else     if     (  X  [  i  -  1  ]     ==     Y  [  j  -  1  ])      L  [  i  ][  j  ]     =     L  [  i     -     1  ][  j     -     1  ]     +     1  ;      else      L  [  i  ][  j  ]     =     Math  .  max  (  L  [  i     -     1  ][  j  ]      L  [  i  ][  j     -     1  ]);      }      }      return     L  [  m  ][  n  ];   }   // Driver Code   let     X     =     'AGTGATG'  ;   let     Y     =     'GTTAG'  ;   let     m     =     X  .  length  ;   let     n     =     Y  .  length  ;   document  .  write  (  'LCS length is '     +      LCS  (  X       Y       m       n  )  +  '  
'
); let s = findLCS ( X Y m n ); for ( let str of s . values ()) document . write ( str + '
'
); // This code is contributed by rag2127 < /script>

Резултат:   

LCS length is 4 GTAG GTTG 

Сложност на времето: Това ще бъде експоненциално, защото използваме рекурсия, за да намерим всички възможни LC. 

Космическа сложност: O (n*n) 
Референции: WikiBooks - Четене на всички LCSS