代码之家  ›  专栏  ›  技术社区  ›  user2722968

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

  •  2
  • user2722968  · 技术社区  · 7 年前

    我有一组弦(小于30),长度从1到~30。我需要找到 至少两个字符串的子集,它们共享尽可能长的前缀+后缀组合 .

    例如,设置为

    Foobar
    Facar
    Faobaron
    Gweron
    Fzobar
    

    前缀/后缀 F/ar 总长度为3,由 Foobar 我是说, Facar Fzobar ;前缀/后缀 F/obar 总长度为5,由 美食家 弗佐巴尔 是的。搜索的前缀/后缀是 离岸价 .

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

    有人知道一个有效的方法来实现这一点吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   saastn    7 年前

    这个怎么样:

    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) 它消除了任何现有的前缀/后缀短于新发现的一个(绞盘被复制)。