在String中查找最长的重复字符

时间:2015-09-07 06:23:21

标签: c# string

假设我有一个像

这样的字符串
string text = "hello dear";

然后我想确定coherented字符的最长重复次数 - 在这种情况下它将是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。我是在正确的轨道上吗?

4 个答案:

答案 0 :(得分:4)

虽然正则表达式或自定义Linq扩展名很好,但是如果你不介意的话,可以按照以前的方式进行。#34;你可以用两个临时变量和一个经典的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);

确实很冗长,但完成了工作。

答案 1 :(得分:3)

如果您更喜欢使用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)
);

使用此扩展程序(取自Use LINQ to group a sequence of numbers with no gaps):

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在其他情况下也非常有用。

答案 2 :(得分:2)

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;

答案 3 :(得分:2)

使用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

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