在String中查找最长重复字符

本文关键字:字符 String 查找 | 更新日期: 2023-09-27 18:11:25

假设我有一个字符串

string text = "hello dear";

然后我想确定连贯字符的最长重复-在这种情况下,它将是ll。如果有多个相同计数的,取任意一个

我试过用linq

解决这个问题
char rchar = text.GroupBy(y => y).OrderByDescending(y => y.Count()).Select(x => x).First().Key;
int rcount = text.Where(x => x == rchar).Count();
string routput = new string(rchar, rcount);

返回ee。我的思路对吗?

在String中查找最长重复字符

另一个使用LINQ的解决方案:

string text = "hello dear";
string longestRun = new string(text.Select((c, index) => text.Substring(index).TakeWhile(e => e == c))
                                   .OrderByDescending(e => e.Count())
                                   .First().ToArray());
Console.WriteLine(longestRun); // ll

它选择以相同重复字符开头的子字符串序列,并使用其中最长的子字符串创建结果字符串。

虽然一个正则表达式或自定义Linq扩展是好的,如果你不介意"做它的旧方式",你可以实现你的结果与两个临时变量和一个经典的foreach循环。

逻辑非常简单,运行时间为O(n)。循环遍历字符串并将当前字符与前一个字符进行比较。

如果相同,增加你的count。如果不同,将其重置为1

然后,如果你的count大于之前记录的最大计数,用你当前的字符覆盖rchar

string text = "hello dear";
char rchar = text[0];
int rcount = 1;
int currentCount = 0;
char previousChar = char.MinValue;
foreach (char character in text)
{
    if (character != previousChar)
    {
        currentCount = 1;
    }
    else
    {
        currentCount++;
    }
    if (currentCount >= rcount)
    {
        rchar = character;
        rcount = currentCount;
    }
    previousChar = character;
}
string routput = new string(rchar, rcount);

如果你喜欢用LINQ来做事情,你可以用一个LINQ扩展来做:

var text = "hello dear";
var result = string.Join("",
    text
    .GroupAdjacentBy((l, r) => (l == r)) /* Create groups where the current character is 
                                         Is the same as the previous character */
    .OrderByDescending(g => g.Count()) //Order by the group lengths
    .First()                           //Take the first group (which is the longest run)
);

有了这个扩展(取自使用LINQ组一个没有间隔的数字序列):

public static class LinqExtensions 
{
    public static IEnumerable<IEnumerable<T>> GroupAdjacentBy<T>(this IEnumerable<T> source, Func<T, T, bool> predicate)
    {
        using (var e = source.GetEnumerator())
        {
            if (e.MoveNext())
            {
                var list = new List<T> { e.Current };
                var pred = e.Current;
                while (e.MoveNext())
                {
                    if (predicate(pred, e.Current))
                    {
                        list.Add(e.Current);
                    }
                    else
                    {
                        yield return list;
                        list = new List<T> { e.Current };
                    }
                    pred = e.Current;
                }
                yield return list;
            }
        }
    }
}

可能有点过分-但我发现GroupAdjacentBy在其他情况下也很有用。

RegEx是一个选项

string text = "hello dear";
string Result = string.IsNullOrEmpty(text) ? string.Empty : Regex.Matches(text, @"(.)'1*", RegexOptions.None).Cast<Match>().OrderByDescending(x => x.Length).First().Value;