最长公共扩展/ LCE | Set 1(介绍和朴素方法)
最长公共扩展 (LCE) 问题考虑字符串s ,并为每一对 (L , R) 计算s的最长子字符串,该子串从 L 和 R 开始。在 LCE 中,在每个查询中我们必须回答从索引 L 和 R 开始的最长公共前缀的长度。
例子:
字符串:“阿巴巴巴”
查询: LCE(1, 2)、LCE(1, 6) 和 LCE(0, 5)
从(1, 2), (1, 6) 和 (0, 5)给出的索引开始查找最长公共前缀的长度。
突出显示“绿色”的字符串是从相应查询的索引 L 和 R 开始的最长公共前缀。我们必须找到从索引- (1, 2), (1, 6) 和 (0, 5)开始的最长公共前缀的长度。
算法(朴素方法)
- 对于形式为 – LCE(L, R) 的每个 LCE 查询,请执行以下操作:
- 将 LCE 'length' 初始化为 0
- 开始逐个字符字符从索引 L 和 R 开始的前缀。
- 如果字符匹配,则该字符在我们的最长公共扩展名中。所以增加“长度”(长度++)。
- 否则,如果字符不匹配,则返回此“长度”。
- 返回的“长度”将是所需的 LCE(L, R)。
执行 :
下面是上述 Naive 算法的 C++ 实现。
CPP
// A C++ Program to find the length of longest
// common extension using Naive Method
#include
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
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
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
输出:
LCE(1, 2) = 1
LCE(1, 6) = 3
LCE(0, 5) = 4
朴素方法分析
时间复杂度:时间复杂度为 O(QN),其中
Q = LCE 查询数
N = 输入字符串的长度
人们可能会感到惊讶,尽管具有更大的渐近时间复杂度,但朴素方法在实际应用中优于其他有效方法(渐近)。我们将在接下来的几集中讨论这个话题。
辅助空间:O(1),就地算法。
应用:
- K-Mismatch Problem->Landau-Vishkin 使用 LCE 作为子程序解决 k-mismatch 问题
- 近似字符串搜索。
- 回文匹配与通配符。
- K-Difference 全局对齐。
在下一组中,我们将讨论如何将 LCE(最长公共扩展)问题简化为 RMQ(范围最小查询)。我们还将讨论更有效的方法来找到最长的公共扩展。
参考 :
- http://www.sciencedirect.com/science/article/pii/S1570866710000377