Open In App

Longest Common Extension / LCE (Introduction and Naive Method)

Last Updated : 31 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

The Longest Common Extension (LCE) problem considers a string s and computes, for each pair (L , R), the longest sub string of s that starts at both L and R. In LCE, in each of the query we have to answer the length of the longest common prefix starting at indexes L and R.

Example: 
String : “abbababba” 
Queries: LCE(1, 2), LCE(1, 6) and LCE(0, 5) 

Find the length of the Longest Common Prefix starting at index given as, (1, 2), (1, 6) and (0, 5).
The string highlighted “green” are the longest common prefix starting at index- L and R of the respective queries. We have to find the length of the longest common prefix starting at index- (1, 2), (1, 6) and (0, 5).

Longest Common Extension

 Algorithm (Naive Method)

  1. For each of the LCE queries of the form – LCE(L, R) do the following: 
    • Initialise the LCE ‘length’ as 0
    • Start comparing the prefix starting from index- L and R character by character.
    • If the characters matches, then this character is in our Longest Common Extension. So increment ‘length’ (length++).
    • Else if the characters mismatch, then return this ‘length’.
  2. The returned ‘length’ will be the required LCE(L, R).

Implementation : 

Below is C++ implementation of above Naive algorithm. 

CPP




// A C++ Program to find the length of longest
// common extension using Naive Method
#include<bits/stdc++.h>
using namespace std;
 
// Structure to represent a query of form (L,R)
struct Query
{
    int L, R;
};
 
// A utility function to find longest common
// extension from index - L and index - R
int LCE(string str, int n, int L, int R)
{
    int length = 0;
 
    while (str[L+length] == str[R+length] &&
            R+length < n)
        length++;
 
    return(length);
}
 
// A function to answer queries of longest
// common extension
void LCEQueries(string str, int n, Query q[],
                                       int m)
{
    for (int i=0; i<m; i++)
    {
        int L = q[i].L;
        int R = q[i].R;
 
        printf("LCE (%d, %d) = %d\n", L, R,
                         LCE(str, n, L, R));
    }
    return;
}
 
// Driver Program to test above functions
int main()
{
    string str = "abbababba";
    int n = str.length();
 
    // LCA Queries to answer
    Query q[] = {{1, 2}, {1, 6}, {0, 5}};
    int m = sizeof(q)/sizeof(q[0]);
 
    LCEQueries(str, n, q, m);
 
    return (0);
}


Java




// A Java Program to find the length of longest
// common extension using Naive Method
import java.util.*;
class GFG
{
 
// Structure to represent a query of form (L,R)
static class Query
{
    int L, R;
    Query(int L, int R)
    {
        this.L = L;
        this.R = R;
    }
};
 
// A utility function to find longest common
// extension from index - L and index - R
static int LCE(String str, int n, int L, int R)
{
    int length = 0;
    while ( R + length < n && str.charAt(L + length) == str.charAt(R + length))
        length++;
    return(length);
}
 
// A function to answer queries of longest
// common extension
static void LCEQueries(String str, int n, Query q[],
                                       int m)
{
    for (int i = 0; i < m; i++)
    {
        int L = q[i].L;
        int R = q[i].R;
        System.out.printf("LCE (%d, %d) = %d\n", L, R,
                         LCE(str, n, L, R));
    }
    return;
}
 
// Driver code
public static void main(String[] args)
{
    String str = "abbababba";
    int n = str.length();
 
    // LCA Queries to answer
    Query q[] = new Query[3];
    q[0] = new Query(1, 2);
    q[1] = new Query(1, 6);
    q[2] = new Query (0, 5);
    int m = q.length;
    LCEQueries(str, n, q, m);
}
}
 
// This code is contributed by gauravrajput1


Python3




# Python Program to find the length of longest
# common extension using Naive Method
 
# A utility function to find longest common
# extension from index - L and index - R
def LCE(string, n, L, R):
    length = 0
    while (R+length < n and string[L+length] == string[R+length]):
        length += 1
    return length
 
# A function to answer queries of longest
# common extension
def LCEQueries(string, n, queries):
    for query in queries:
        L = query[0]
        R = query[1]
        print("LCE ({}, {}) = {}".format(L, R, LCE(string, n, L, R)))
 
# Driver Program to test above functions
if __name__ == '__main__':
    string = "abbababba"
    n = len(string)
    # LCA Queries to answer
    queries = [(1, 2), (1, 6), (0, 5)]
    LCEQueries(string, n, queries)
     
# This code is contributed by Aman Kumar


C#




// A C# Program to find the length of longest
// common extension using Naive Method
using System;
public class GFG
{
 
  // Structure to represent a query of form (L,R)
  public
    class Query
    {
      public
        int L, R;
      public
        Query(int L, int R)
      {
        this.L = L;
        this.R = R;
      }
    };
 
  // A utility function to find longest common
  // extension from index - L and index - R
  static int LCE(String str, int n, int L, int R)
  {
    int length = 0;
    while ( R + length < n && str[L + length] == str[R + length])
      length++;
    return(length);
  }
 
  // A function to answer queries of longest
  // common extension
  static void LCEQueries(String str, int n, Query []q,
                         int m)
  {
    for (int i = 0; i < m; i++)
    {
      int L = q[i].L;
      int R = q[i].R;
      Console.WriteLine("LCE (" + L + ", " + R +
                        ") = " + LCE(str, n, L, R));
    }
    return;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    String str = "abbababba";
    int n = str.Length;
 
    // LCA Queries to answer
    Query []q = new Query[3];
    q[0] = new Query(1, 2);
    q[1] = new Query(1, 6);
    q[2] = new Query (0, 5);
    int m = q.Length;
    LCEQueries(str, n, q, m);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
// A Javascript Program to find the length of longest
// common extension using Naive Method
 
// Structure to represent a query of form (L,R)
class Query
{
    constructor(L,R)
    {
        this.L = L;
        this.R = R;
    }
}
 
// A utility function to find longest common
// extension from index - L and index - R
function LCE(str,n,L,R)
{
    let length = 0;
    while ( R + length < n && str[L + length] == str[R + length])
        length++;
    return(length);
}
 
// A function to answer queries of longest
// common extension
function LCEQueries(str,n,q,m)
{
    for (let i = 0; i < m; i++)
    {
        let L = q[i].L;
        let R = q[i].R;
        document.write("LCE ("+L+", "+R+") = "+LCE(str, n, L, R)+"<br>");
    }
    return;
}
 
// Driver code
let  str = "abbababba";
let n = str.length;
 
// LCA Queries to answer
let q = new Array(3);
q[0] = new Query(1, 2);
q[1] = new Query(1, 6);
q[2] = new Query (0, 5);
let m = q.length;
LCEQueries(str, n, q, m);
 
// This code is contributed by unknown2108
</script>


Output

LCE (1, 2) = 1
LCE (1, 6) = 3
LCE (0, 5) = 4

Analysis of Naive Method :

Time Complexity: The time complexity is O(Q.N), where 

  • Q = Number of LCE Queries 
  • N = Length of the input string 

One may be surprised that the although having a greater asymptotic time complexity, the naive method outperforms other efficient method(asymptotically) in practical uses. We will be discussing this in coming sets on this topic.

Auxiliary Space: O(1), in-place algorithm.

Applications: 

  1. K-Mismatch Problem->Landau-Vishkin uses LCE as a subroutine to solve k-mismatch problem
  2. Approximate String Searching.
  3. Palindrome Matching with Wildcards.
  4. K-Difference Global Alignment.

In the next sets we will discuss how LCE (Longest Common Extension) problem can be reduced to a RMQ (Range Minimum Query). We will also discuss more efficient methods to find the longest common extension.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads