在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
。我的思路对吗?
另一个使用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;