获取两个字符串的公共前缀

get common prefix of two string

我试图在 C# 中比较两个字符串,但我无法找到一种方法来获得我需要的结果而无需自己构建一些东西。

字符串:

TestasdOne
TestasdTwo

结果:

Testasd

我试过 linq 但无法正常工作。 我试过了 Google.

提前致谢。

使用 linq 你可以做到这一点。

string str1 = "TestasdOne";
string str2 = "TestasdTwo";

string similar = string.Join("", str1.TakeWhile((ch, i) => i < str2.Length && str2[i] == ch));

这将获取第一个字符串的字符,而其字符与相同索引处的第二个字符串的字符相同。

这里是non-linq版本,效率更高,清晰易读

public static string CommonPrefix(string a, string b)
{
    if (a == null)
        throw new ArgumentNullException(nameof(a));

    if (b == null)
        throw new ArgumentNullException(nameof(b));

    var min = Math.Min(a.Length, b.Length);
    var sb = new StringBuilder(min);
    for (int i = 0; i < min && a[i] == b[i]; i++)
        sb.Append(a[i]);

    return sb.ToString();
}

像这样使用

Console.WriteLine(CommonPrefix("TestasdOne", "TestasdTwo")); //Testasd

一个解决方案可能是向 LInq 添加一个适用于字符串和任何 IEnumerable<T>

的扩展方法

这是一种小函数,当你觉得它们在 Linq 中遗漏时,可以快速编写。

public static class CommonPartExtension
{
    public static IEnumerable<T> CommonPart<T>(this IEnumerable<T> source1, 
                                                    IEnumerable<T> source2)
    {
        IEnumerator<T> enumerator1 = source1.GetEnumerator();
        IEnumerator<T> enumerator2 = source2.GetEnumerator();
        while( enumerator1.MoveNext() && enumerator2.MoveNext())
        {
            if ( enumerator1.Current.Equals(enumerator2.Current) )
                yield return enumerator2.Current;
            else
                yield break ;
        }
    }
}

用法:

        string s1 = "TestasdOne";
        string s2 = "TestasdTwo";
        Console.WriteLine("CommonPart " +
            new String( s1.CommonPart(s2).ToArray()));

此致

这是一个针对任意字符串数组并进行了一些优化的解决方案。我不会即时组合结果,而是计算长度。

    private static string GetCommonPrefix(params string[] values)
    {
        string result = string.Empty;
        int? resultLength = null;

        if (values != null)
        {
            if (values.Length > 1)
            {
                var min = values.Min(value => value.Length);

                for (int charIndex = 0; charIndex < min; charIndex++)
                {
                    for (int valueIndex = 1; valueIndex < values.Length; valueIndex++)
                    {
                        if (values[0][charIndex] != values[valueIndex][charIndex])
                        {
                            resultLength = charIndex;
                            break;
                        }
                    }

                    if (resultLength.HasValue)
                    {
                        break;
                    }
                }

                if (resultLength.HasValue &&
                    resultLength.Value > 0)
                {
                    result = values[0].Substring(0, resultLength.Value);
                }
            }
            else if (values.Length > 0)
            {
                result = values[0];
            }
        }

        return result;
    }