Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 计算richtextbox中所有单词的最有效方法是什么?_C#_Wpf_Performance_Richtextbox_Word Count - Fatal编程技术网

C# 计算richtextbox中所有单词的最有效方法是什么?

C# 计算richtextbox中所有单词的最有效方法是什么?,c#,wpf,performance,richtextbox,word-count,C#,Wpf,Performance,Richtextbox,Word Count,我正在编写一个文本编辑器,需要提供一个实时单词计数。现在我正在使用这种扩展方法: 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

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

 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文本运行一次单词计数(如果选择开始与上次运行该方法时不同)。问题是,在处理很长的文件时,字数会变慢。为了解决这个问题,我考虑只对当前段落进行字数统计,记录每次的字数,并将其与上次进行字数统计时的字数进行比较。然后将两者之间的差异添加到总字数中。 这样做会导致许多复杂情况(如果用户粘贴,如果用户删除段落,等等) 这是提高我词数的合理方法吗?还是有什么我不知道的东西可以让它变得更好

编辑: 在不同的线程上运行单词计数是否有效?威尔研究,我对线程知之甚少


我使用的示例文本:

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

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

,在大文件上应该可以更快地获得准确的字数。

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

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

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

您的方法实际上比建议的
String.Split
方法快,事实上,x86的速度快了近三倍,x64的速度快了两倍多。我怀疑JIT打乱了你的计时,在你第一次跑步时,一定要让你的微基准跑两次,因为JIT会占据绝大多数时间。而且因为
String.Split
已经被加密,所以它不需要编译为本机代码,因此看起来会更快

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

这是一个测试


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

谢谢您的回答,但这种方法不够准确。刚才我在我的原始帖子中测试了这个方法,在一个文档中测试了这个方法,根据微软的Word,这个文档有2142个单词长。这篇文章中的方法数为2165,而我的原始文章中的方法数为2141。@highone-发布这段文本样本…我看看有什么区别,只要稍微调整一下,我们就可以匹配它。我不得不将文本作为答案发布,因为它太大,无法放入评论中。我是stackoverflow新手,不确定我是否应该将其作为社区wiki发布。@highone-我更新了答案,我用该方法得到2142条消息……看看是否对你有用。@highone-我做了一些基准测试,该方法的速度至少是其他方法的两倍。如果速度是你的主要要求,那么这就是你想要使用的方法+1不幸的是,regex比我目前使用的方法慢得多。@highone-我在尼克回答的评论中指出了这一点。你有一个折衷,你想牺牲一些速度的准确性?正如我上面提到的,当涉及到某些标点符号时,即使是单词也是不正确的。这完全取决于你想要什么。拆分始终是最快的方法,除非它是一个新文档,并且您跟踪用户类型的词数。您跟踪用户类型的词数到底是什么意思?