我正在编写文本编辑器,需要提供现场单词计数。现在,我正在使用此扩展方法:

 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的文本上运行(如果选择启动与上次方法播放的情况不同)。问题在于,在处理很长的文件时,单词计数会慢。为了解决这个问题,我正在考虑只在当前段落上运行单词计数,每次记录单词计数,并将其与上次count count运行的单词计数进行比较。然后,将两者之间的差异添加到总单词计数中。这样做会导致许多并发症(如果用户粘贴,如果用户删除了段落,ECT。)这是改善我的单词计数的逻辑方式吗?还是我不知道哪些东西会使它变得更好?

编辑:在另一个线程上运行单词计数是否有效?我对线程的了解不多,会研究。

我使用的示例文本:

有帮助吗?

解决方案

您可以根据白空间进行更简单的单词计数:

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

MSDN提供了此示例, ,应该在大文件上给您准确的单词计数。

其他提示

您还可以使用一个非常简单的正则态度,该正则认为至少一个单词字符和/或撇号来捕获收缩:

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

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

您的方法实际上比提议更快 String.Split 方法,实际上在x86上快了近三倍,x64的速度快两倍以上。我怀疑jit弄乱了您的时间,始终运行您的微晶测量,因为JIT会占据 绝大多数 在您的第一次跑步期间的时间。因为 String.Split 已经不需要,不需要将其编译到本机代码,因此似乎会更快。

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

测试::这是一个测试

这也有道理 String.Split 没有执行任何魔法,如果创建许多字符串的数组比简单地迭代字符串中的单个字符更快,我会感到非常惊讶。当我尝试时,在弦上供应弦显然已经得到了高度优化 unsafe 指针算术,实际上比简单的一点慢一点 foreach. 。我真的怀疑有什么方法可以更快地执行此操作,除了明智地了解文本中的哪些部分需要单词计数。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top