代码之家  ›  专栏  ›  技术社区  ›  Rowland Shaw

如何在两个字符串中找到共同的后缀?

  •  1
  • Rowland Shaw  · 技术社区  · 15 年前

    我试图实现一些在多个字符串之间找到公共后缀的东西,为了便于说明,请考虑以下内容:

    "The quick brown fox"
    "The not so quick brown fox"
    "The smelly brown fox"
    "The vicious brown fox"
    

    对于人类来说,很明显这里的共同后缀是 " brown fox"

    编辑: 去掉双反转(这意味着我们不需要转换成char数组)可以获得相当好的性能,就记录而言,我的实现看起来有点像:

        private string GetCommonSuffix(string[] lines)
        {
            int lineCount = lines.GetLength(0);
    
            string currentSuffix = lines[0];
            int currentSuffixLength = currentSuffix.Length;
            for (int i = 1; i < lineCount; i++)
            {
                string thisLine = lines[i];
                if (!thisLine.EndsWith(currentSuffix))
                {
                    int thisLineLength = thisLine.Length;
                    int maxPossible = thisLineLength < currentSuffixLength ? thisLineLength : currentSuffixLength;
    
                    if (maxPossible == 0)
                    {
                        return string.Empty;
                    }
    
                    for (int j = 1; j < maxPossible; j++)
                    {
                        if( currentSuffix[ currentSuffixLength - j ] != thisLine[ thisLineLength - j ] )
                        {
                            currentSuffix = currentSuffix.Substring(currentSuffixLength - j + 1, j - 1);
                            currentSuffixLength = j - 1;
                            break;
                        }
                    }
                }
            }
    
            return currentSuffix;
        }
    
    3 回复  |  直到 15 年前
        1
  •  3
  •   Jon Skeet    15 年前

    首先,不需要将字符串转换为char数组。可以在字符串中使用索引器来获取单个字符。

    也许值得把它看作 而不是一根绳子。。。每个成对比较都会给出一个最大值,最后的数字(后缀的大小)是这些最大值的最小值。

    因此,有两种方法建议自己:

    • 从0开始(始终有效)并逐步向上:检查1是否有效(即所有字符串以相同字符结尾),然后移到2(通过检查倒数第二个字符)等
    • 从无穷开始,然后对 最大长度。你当然不需要 成对比较-只需将每个字符串与第一个字符串进行比较就可以了。

        2
  •  1
  •   The Archetypal Paul    15 年前

    在完成所有比较之前,也不需要反转当前候选公共后缀。

    但是,您可以通过将索引数组保留在每个字符串的位置、将每个字符串初始化为字符串的长度(减1)并从末尾开始向后工作、遍历所有字符串来避免反转。

        3
  •  0
  •   jim tollan    15 年前

    考虑到您可能希望保留以前计算的值,这可能是记忆递归函数的一个很好的候选者。

    基本示例: http://weblogs.asp.net/podwysocki/archive/2008/08/01/recursing-into-recursion-memoization.aspx

    或: http://explodingcoder.com/blog/content/painless-caching-memoization-net

    可能合适,可能没用:)