字符串集中最长的前缀+后缀组合

时间:2018-06-23 15:38:07

标签: string algorithm string-matching

我有一组长度在1到〜30之间的字符串(少于30个)。我需要找到至少两个字符串的子集,这些子集共享最长的前缀+后缀组合

例如,将集合设为

Foobar
Facar
Faobaron
Gweron
Fzobar

前缀/后缀F/ar的组合长度为3,并且由FoobarFacarFzobar共享;前缀/后缀F/obar的总长度为5,并且由FoobarFzobar共享。搜索的前缀/后缀为F/obar

请注意,不要将这与最长的公共前缀/后缀混淆,因为集合中只有两个或多个字符串需要共享相同的前缀和后缀。还要注意,前缀和后缀的长度之和是要最大化的,因此需要将两者都考虑在内。前缀或后缀可以是空字符串。

有人知道实现此目标的有效方法吗?

1 个答案:

答案 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)部分中,它消除了任何比新发现的前缀/后缀短的现有前缀/后缀(绞盘重复)。