3

我正在编写一个文本编辑器,需要提供实时字数。现在我正在使用这个扩展方法:

 public static int WordCount(this string s)
    {
        s = s.TrimEnd();
        if (String.IsNullOrEmpty(s)) return 0;
        int count = 0;
        bool lastWasWordChar = false;
        foreach (char c in s)
        {
            if (Char.IsLetterOrDigit(c) || c == '_' || c == '\'' || c == '-')
            {
                lastWasWordChar = true;
                continue;
            }
            if (lastWasWordChar)
            {
                lastWasWordChar = false;
                count++;
            }
        }
        if (!lastWasWordChar) count--;
        return count + 1;
    }

我已将其设置为每十分之一秒在richtextbox 的文本上运行一次字数(如果选择开始与上次运行该方法时的开始不同)。问题是在处理非常长的文件时字数会变慢。为了解决这个问题,我正在考虑只在当前段落上运行字数,每次记录字数并将其与上次运行字数时的字数进行比较。然后它将两者之间的差异添加到总字数中。这样做会导致很多并发症(如果用户粘贴,如果用户删除段落等)这是提高我的字数的合乎逻辑的方法吗?或者有什么我不知道的东西会让它变得更好吗?

编辑:在不同的线程上运行字数统计会起作用吗?我对线程不太了解,将研究。

我使用的示例文本:

4

3 回答 3

12

您可以根据空格进行更简单的字数统计:

public static int WordCount(this string s)
{
  return s.Split(new char[] {' '}, 
    StringSplitOptions.RemoveEmptyEntries).Length;
}

MSDN 提供了这个例子,在大文件上应该更快地为您提供准确的字数统计。

于 2010-02-09T01:40:58.777 回答
4

您还可以使用一个非常简单的正则表达式来查找至少一个单词字符和/或撇号来捕获缩写:

public static int WordCount(this string s) 
{
    return Regex.Matches(s, @"[\w']+").Count;
}

这将返回 2141 个匹配项(在这种情况下实际上比 Word 更正确,因为 Word 将单个星号计为句子中的一个单词“通过用她的手指戳 *”)。

于 2010-02-09T03:44:34.050 回答
0

您的方法实际上比建议的String.Split方法快,在 x86 上快了近三倍,实际上在 x64 上快了两倍多。我怀疑 JIT 弄乱了你的时间,总是运行你的微基准测试两次,因为 JIT 将在你第一次运行期间占据绝大多数时间。而且因为String.Split已经过 NGEN,它不需要编译为本机代码,因此看起来会更快。

更不用说它也更准确,String.Split将在这里计算7个单词:

测试: : 这是一个测试

这也是有道理的,String.Split不会执行任何魔法,如果创建一个包含许多字符串的数组比简单地迭代字符串中的单个字符要快,我会感到非常惊讶。当我尝试指针算法时,对字符串的 foreaching 显然已经高度优化unsafe,它实际上比简单的foreach. 我真的怀疑有什么方法可以更快地做到这一点,除了聪明地知道你的文本中的哪些部分需要字数统计。

于 2010-02-10T23:12:27.893 回答