当前位置: 首页 > 编程语言 > C#

从文本C#中删除停用词分享

时间:2023-04-10 13:00:57 C#

C#学习教程:去除文本中的停用词试试","你自己","之前"};stringinput="你问之前自己试过吗";foreach(arrToCheck中的字符串字){input=input.Replace(word,"");这是完成这项任务的最佳方式吗,尤其是当我有(450)个停用词并且输入字符串很长时?我更喜欢使用替换方法,因为我想删除以不同形态出现的停用词。例如,如果停用词是“do”,则从(do,do,etc.)中删除“do”。有什么更好、最快的方法来处理这个问题的建议吗?提前致谢。我可以推荐一个StringBuilder吗?http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspxstring[]arrToCheck=newstring[]{"try","yourself","before"};StringBuilderinput=newStringBuilder("问之前你自己试过吗");foreach(arrToCheck中的字符串字){input.Replace(word,"");因为它在它自己的数据结构中完成所有处理并且不会分配数百个新字符串,所以我相信您会发现它的内存效率更高。这个Prematureoptimization有几个方面给出的方法是有效的并且易于理解/维护。它会导致性能问题吗?如果没有,那就不用担心了。如果它曾经引起问题,请查看它。预期结果在此示例中,您希望输出是什么?“Didyouthisasking”或“Didyouthisasking”你在“trying”和“before”的末尾添加了空格,而不是“yourself”。为什么?打字错误?string.Replace()区分大小写。如果您关心大小写,则需要修改您的代码。使用部分是混乱的。单词以不同的时态变化。“做”的例子去掉了“做”这个词,但是“接受”和“接受”呢?停用词的顺序很重要,因为您正在更改输入。有可能(我不知道有多大可能但可能)更改后输入中没有出现的单词“出现”。每次回去都要重新检查吗?您真的需要删除该部分吗?优化当前方法将对输入字符串进行n次处理,其中n是要编辑的单词数,每次发生替换时都会创建一个新字符串。这很慢。使用StringBuilder(上面的akatakritos)会加快速度,所以我会先尝试一下。重新测试看这是否足够快。您可以使用Linq仅通过“显示”进行编辑。您还需要允许标点符号并决定它们应该发生什么。EndEdit[TestMethod]publicvoidRedactTextLinqNoPartials(){vararrToCheck=newstring[]{"try","yourself","before"};varinput="你问之前自己试过吗";varoutput=string.Join("",input.Split('').Where(wrd=>!arrToCheck.Contains(wrd)));Assert.AreEqual("Didyouthisasking",output);}将删除所有整个单词(和空格。不可能看到单词被删除的位置)但没有一些基准我不会说它更快。使用linq处理部分可能会变得混乱,但如果我们只需要一次通过(不检查“找到的”单词)[TestMethod]publicvoidRedactTextLinqPartials(){vararrToCheck=newstring[]{"try","yourself","之前”,“问”};varinput="你问之前自己试过吗";varoutput=string.Join("",input.Split('').Select(wrd=>{varfound=arrToCheck.FirstOrDefault(chk=>wrd.IndexOf(chk)!=-1);返回找到!=null?wrd.Replace(found,""):wrd;}).Where(wrd=>wrd!=""));Assert.AreEqual("你这样做了吗",output);}仅从这个角度来看,我会说它比string.Replace()慢,但没有一些数字就无法判断。这肯定更复杂。底线String.Replace()方法(修改为使用字符串构建器并且不区分大小写)看起来是一个很好的第一个解决方案。艾伦,在尝试任何更复杂的事情之前,我会就可能的表现进行一次心与心的交流。要从句子中删除字符串列表并将结果聚合在一起的简单方法,您可以这样做:varinput="Didyoutrythisyourselfbeforeasking";vararrToCheck=new[]{“尝试”,“你自己”,“之前”};varresult=input.Split(arrToCheck,arrToCheck.Count(),StringSplitOptions.None).Aggregate((first,second)=>first+second);这将拆分原始字符串,并使用拆分数组中的结果集来创建最终字符串。结果将是“Didyouthisbeforeasking”缩短代码并使用LINQstring[]arrToCheck=newstring[]{“try”,“yourself”,“before”};vartest=newStringBuilder("问之前你自己试过吗");arrToCheck.ForEach(x=>test=test.Replace(x,""));Console.Writeln(test.ToString());String.Join("",input.Split('').Where(w=>stop.Where(sW=>sW==w).FirstOrDefault()==null).ToArray());干得好:varwords_to_remove=newHashSet{"try","yourself","before"};stringinput="你问之前自己试过吗";stringoutput=string.Join("",input.Split(new[]{'','t','n','r'/*等...*/}).Where(word=>!words_to_remove.包含(单词)));控制台.WriteLine(输出);这会打印:DidyouthisaskingHashSetprovidesextremelyfastlookups,Sowords_to_remove450elementsshouldn'thaveanyproblem.此外,我们仅遍历输入字符串一次(而不是像您的示例那样移动每个单词)。但是,如果输入字符串很长,可以通过不将拆分结果一次全部保存在内存中来提高内存效率(如果不是更快的话)。不仅要删除“doing”,还要删除“doing”、“doing”等...您必须在words_to_remove中包含所有这些变体。如果你想以一般方式删除前缀,这可以(相对)有效地删除一些单词(或输入字符串的后缀树),但是当“do”不是应该是的东西的前缀时该怎么办删除,例如“做了”?或者当它是不应该删除的东西的前缀时,比如“狗”?顺便说一句,要删除单词,无论大小写如何,只需将适当的不区分大小写的比较器传递给HashSet构造函数,例如StringComparer.CurrentCultureIgnoreCase。—编辑—这是另一个选项:varwords_to_remove=new[]{"","try","yourself","before"};//注意空格!stringinput="你问之前自己试过吗";字符串输出=string.Join("",input.Split(words_to_remove,StringSplitOptions.RemoveEmptyEntries));我猜应该会比较慢(除非string.Split内部使用哈希表),但是很好很整洁;)以上是C#学习教程:删除文本C#中的停用词,分享所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: