我有一组长度在1到〜30之间的字符串(少于30个)。我需要找到至少两个字符串的子集,这些子集共享最长的前缀+后缀组合。
例如,将集合设为
Foobar
Facar
Faobaron
Gweron
Fzobar
前缀/后缀F/ar
的组合长度为3,并且由Foobar
,Facar
和Fzobar
共享;前缀/后缀F/obar
的总长度为5,并且由Foobar
和Fzobar
共享。搜索的前缀/后缀为F/obar
。
请注意,不要将这与最长的公共前缀/后缀混淆,因为集合中只有两个或多个字符串需要共享相同的前缀和后缀。还要注意,前缀和后缀的长度之和是要最大化的,因此需要将两者都考虑在内。前缀或后缀可以是空字符串。
有人知道实现此目标的有效方法吗?
答案 0 :(得分:0)
如何?
maxLen := -1;
for I := 0 to Len(A) - 1 do
if Len(A[I]) > maxLen then // (1)
for J := 0 to Len(A[I]) do
for K := 0 to Len(A[I]) - J do
if J+K > maxLen then // (2)
begin
prf := LeftStr(A[I], J);
suf := RightStr(A[I], K);
found := False;
for m := 0 to Len(sufList) - 1 do
if (sufList[m] = suf) and (prfList[m] = prf) then
begin
maxLen := J+K;
Result := prf+'/'+suf;
found := True;
// (3)
n := 0;
while n < Len(sufList) do
if Len(sufList[n])+Len(prfList[n]) <= maxLen then
begin
sufList.Delete(n);
prfList.Delete(n);
end
else
Inc(n);
// (end of 3)
Break;
end;
if not found then
begin
sufList.Add(suf);
prfList.Add(prf);
end;
end;
在此示例中,maxLen
保留到目前为止找到的最长前缀/后缀的长度之和。其中最重要的部分是标记为(2)
的行。它绕过了很多不必要的字符串比较。在(3)
部分中,它消除了任何比新发现的前缀/后缀短的现有前缀/后缀(绞盘重复)。