比较字符串是否相等
本文关键字:是否 字符串 比较 | 更新日期: 2023-09-27 17:52:49
我想比较一组字符串,并返回相等的部分,直到出现不相等的部分。(并删除traling空白(。
示例:
List<string> strList = new List<string>
{
"string xyz stop",
"string abc stop",
"string qrt stop"
};
string result = GetEqualName(strList); // This should return "string"
我做了以下方法,工作
string GetEqualName(IEnumerable<string> strList)
{
string outString = "";
bool firstTime = true;
foreach (var subString in strList)
{
if (firstTime)
{
outString = subString;
firstTime = false;
}
else
{
string stringBuilder = "";
for (int i = 0; i < outString.Count(); i++)
{
if (outString[i] == subString[i])
stringBuilder = stringBuilder + outString[i];
else
break;
}
outString = stringBuilder;
}
}
outString = outString.TrimEnd(' '); // Remove traling whitespace
return outString;
}
我只是觉得这是可以用几行字完成的事情,我做得太过火了。你们有什么建议吗?
您可以将两个字符串Zip
放在一起,取相等的对,然后创建一个包含这些字符的字符串。
public static string LargestCommonPrefix(string first, string second)
{
return new string(first.Zip(second, Tuple.Create)
.TakeWhile(pair => pair.Item1 == pair.Item2)
.Select(pair => pair.Item1)
.ToArray());
}
一旦解决了组合两个字符串的问题,就可以很容易地将其应用于字符串序列:
public static string LargestCommonPrefix(IEnumerable<string> strings)
{
return strings.Aggregate(LargestCommonPrefix);
}
这个小函数与您的版本基本相同,但更短。
string GetEqualName(IEnumerable<string> strList)
{
int limit = strList.Min(s => s.Length);
int i = 0;
for (; i < limit; i++)
{
if (strList.Select(s => s.Substring(0,i+1)).Distinct().Count() > 1)
{
break;
}
}
return strList.First().Substring(0, i).Trim();
}
这里有一个不同的方法,可以满足您的需要。我使用HashSet<string>
:从左到右查找最长的公共子字符串
string GetCommonStartsWith(IEnumerable<string> strList, StringComparer comparer = null)
{
if(!strList.Any() || strList.Any(str => string.IsNullOrEmpty(str)))
return null;
if(!strList.Skip(1).Any())
return strList.First(); // only one
if(comparer == null) comparer = StringComparer.CurrentCulture;
int commonLength = strList.Min(str => str.Length);
for (int length = commonLength; length > 0; length--)
{
HashSet<string> duptester = new HashSet<string>(comparer);
string first = strList.First().Substring(0, length).TrimEnd();
duptester.Add(first);
bool allEqual = strList.Skip(1)
.All(str => !duptester.Add(str.Substring(0, length).TrimEnd()));
if (allEqual)
return first;
}
return null;
}
这里有一个版本,它使用的LINQ比其他一些答案更少,而且可能更具性能。
string GetEqualName(IEnumerable<string> strList)
{
StringBuilder builder = new StringBuilder();
int minLength = strList.Min(s => s.Length);
for (int i = 0; i < minLength; i++)
{
char? c = null;
foreach (var s in strList)
{
if (c == null)
c = s[i];
else if (s[i] != c)
return builder.ToString().TrimEnd();
}
builder.Append(c);
}
return builder.ToString().TrimEnd();
}