在C#中查找字符串的尾随空格的最佳方法是什么?

时间:2019-07-19 11:09:27

标签: c#

我可以说数百万个带或不带尾部空格的字符串。我想计算每个字符串中的尾随空格数。

我正在为每个字符串这样做。

int count = input.Length - input.TrimEnd().Length;

但是我认为这样做效率不高,因为我通过为每个字符串使用TrimEnd()方法来创建不必要的字符串。

我曾经考虑过使用另一种方法来计算尾随空格,方法是对每个字符反向遍历字符串,并检查直到第一个非空格字符(将计数加1)。

有没有更快,更有效的方法来做到这一点?字符串很小,但以百万计。

2 个答案:

答案 0 :(得分:3)

编辑:我没有做任何分析,而是将其放入扩展方法中:

void Main()
{
    string test = "StackOverflow     ";
    int count = test.WhiteSpaceAtEnd();
}

public static class StringExtensions
{
    public static int WhiteSpaceAtEnd(this string self)
    {
        int count = 0;
        int ix = self.Length - 1;
        while (ix >= 0 && char.IsWhiteSpace(self[ix--]))
            ++count;

        return count;
    }
}

答案 1 :(得分:1)

这里有2种可能的解决方案,一种使用for循环,另一种使用Linq。这些都是扩展方法的形式。

public static class StringExtensions {
    public static int CountTrailingSpaces(this string s) {
        int count = 0;
        for (int i = s.Length- 1; i >= 0; i--) {
            if (Char.IsWhiteSpace(s[i])) {
                count++;
            }
            else {
                return count;
            }
        }

        return count;
    }
    public static int CountTrailingSpacesLinq(this string s) {
        return s.Reverse().TakeWhile(Char.IsWhiteSpace).Count();
    }
}

然后您可以按以下方式调用它们:

static void Main(string[] args) {
    string s = "test  ";

    Console.WriteLine(s.CountTrailingSpaces());
    Console.WriteLine(s.CountTrailingSpacesLinq());
}

使用此测试代码收到的输出是:

  

2

     

2

添加一些快速性能指标。我强烈建议使用CountTrailingSpaces。如下所示,这明显更快。

for方法相比,使用linq循环对字符串执行1,000,000次操作所花费的总滴答数明显不同。

对于:803529滴答声

Linq:7171201滴答声

性能测试代码如下所示:

class Program {
    private static Random Random;
    private static Stopwatch Stopwatch;

    static void Main(string[] args) {
        Random = new Random(Guid.NewGuid().GetHashCode());
        Stopwatch = new Stopwatch();

        decimal forLoop = 0;
        decimal linq = 0;
        for (int i = 0; i < 1000000; i++) {
            string s = RandomString(100);

            Stopwatch.Restart();
            s.CountTrailingSpaces();
            Stopwatch.Stop();

            forLoop += Stopwatch.ElapsedTicks;

            Stopwatch.Restart();
            s.CountTrailingSpacesLinq();
            Stopwatch.Stop();

            linq += Stopwatch.ElapsedTicks;
        }

        Console.WriteLine($"For:\t{forLoop}");
        Console.WriteLine($"Linq:\t{linq}");
    }
    private static string RandomString(int length) {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789          ";
        return new string(Enumerable.Repeat(chars, length)
          .Select(s => s[Random.Next(s.Length)]).ToArray());
    }
}

public static class StringExtensions {
    public static int CountTrailingSpaces(this string s) {
        int count = 0;
        for (int i = s.Length - 1; i >= 0; i--) {
            if (Char.IsWhiteSpace(s[i])) {
                count++;
            }
            else {
                return count;
            }
        }

        return count;
    }
    public static int CountTrailingSpacesLinq(this string s) {
        return s.Reverse().TakeWhile(Char.IsWhiteSpace).Count();
    }
}