如何在 C# 中查找字符串中的所有双字符

本文关键字:字符 查找 字符串 | 更新日期: 2023-09-27 18:33:48

我正在尝试使用 C# 获取字符串中所有双精度字符的计数,即"ssss"应该是两个双精度而不是三个双精度。

例如,现在我必须在字符串中做一个 for 循环,就像这样

string s="shopkeeper";
for(int i=1;i<s.Length;i++) if(s[i]==s[i-1]) d++;

最后d的值应1

有没有更短的方法可以做到这一点? 在 linq 或正则表达式中? 性能影响是什么,最有效的方法是什么?感谢您的帮助

我已经阅读了[如何检查字符串c#中的重复字母]和 这很有帮助,但不解决双字符,我正在寻找 双字符

如何在 C# 中查找字符串中的所有双字符

尝试按照正则表达式提取任何双字符:"(.)'1"

UPD:简单示例:

foreach (var match in Regex.Matches("shhopkeeper", @"(.)'1"))
   Console.WriteLine(match);

这有效:

var doubles =
    text
        .Skip(1)
        .Aggregate(
            text.Take(1).Select(x => x.ToString()).ToList(),
            (a, c) =>
            {
                if (a.Last().Last() == c)
                    a[a.Count - 1] += c.ToString();
                else
                    a.Add(c.ToString());
                return a;
            })
        .Select(x => x.Length / 2)
        .Sum();

我给我这些结果:

"shopkeeper" -> 1
"beekeeper" -> 2
"bookkeeper" -> 3
"boookkkeeeper" -> 3
"booookkkkeeeeper" -> 6

首先,我想提一下,这个问题没有"自然的"LINQ 解决方案,因此与简单的for循环相比,每个基于 LINQ 的标准解决方案都将是丑陋且效率极低的。

但是,对于此问题和类似问题,有一个LINQ"精神"解决方案,例如链接的如何检查字符串c#中的重复字母,或者例如,如果您想找到的不是双打s,而是三重s,四重s等

常见的子问题是,给定某个元素序列,为具有相同值的连续元素生成一个新的(value, count)对组序列。

可以使用这样的自定义扩展方法完成(方法的名称可能不同,对于这一点来说不是必需的(:

public static class EnumerableEx
{
    public static IEnumerable<TResult> Zip<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> resultSelector, IEqualityComparer<TSource> comparer = null)
    {
        if (comparer == null) comparer = EqualityComparer<TSource>.Default;
        using (var e = source.GetEnumerator())
        {
            for (bool more = e.MoveNext(); more;)
            {
                var value = e.Current;
                int count = 1;
                while ((more = e.MoveNext()) && comparer.Equals(e.Current, value)) count++;
                yield return resultSelector(value, count);
            }
        }
    }
}

将此功能与标准 LINQ 结合使用,可以轻松解决原始问题:

var s = "shhopkeeperssss";
var countDoubles = s.Zip((value, count) => count / 2).Sum();

但也

var countTriples = s.Zip((value, count) => count / 3).Sum();

var countQuadruples = s.Zip((value, count) => count / 4).Sum();

或链接中的问题

var repeatedChars = s.Zip((value, count) => new { Char = value, Count = count })
    .Where(e => e.Count > 1);

等。