Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.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#:高效地搜索大字符串以查找其他字符串_C#_String - Fatal编程技术网

C#:高效地搜索大字符串以查找其他字符串

C#:高效地搜索大字符串以查找其他字符串,c#,string,C#,String,我使用C#在大于等于4kb的大字符串中连续搜索多个字符串“关键字”。这段代码不断循环,睡眠并没有在保持合理速度的同时充分减少CPU的使用。陷入困境的是关键词匹配方法 我发现了一些可能性,所有这些都提供了类似的效率 (一) -我没有足够的关键字,这是最有效的算法 2) 正则表达式。使用实例级别编译的正则表达式。 -提供了比我需要的更多的功能,但效率不够 3) String.IndexOf。 -我需要做一个“智能”版本的这个,因为它提供足够的效率。循环遍历每个关键字并调用IndexOf并不能减少它

我使用C#在大于等于4kb的大字符串中连续搜索多个字符串“关键字”。这段代码不断循环,睡眠并没有在保持合理速度的同时充分减少CPU的使用。陷入困境的是关键词匹配方法

我发现了一些可能性,所有这些都提供了类似的效率

(一) -我没有足够的关键字,这是最有效的算法

2) 正则表达式。使用实例级别编译的正则表达式。 -提供了比我需要的更多的功能,但效率不够

3) String.IndexOf。 -我需要做一个“智能”版本的这个,因为它提供足够的效率。循环遍历每个关键字并调用IndexOf并不能减少它


有人知道我可以使用什么算法或方法来实现我的目标吗?

我没有尝试过,但你看过吗?显然,它在最坏情况下的复杂度很差,但通常是相当好的

你的关键词看起来像什么?特别是,它们是否总是由空格(或类似的东西)分隔?如果是这样,您基本上可以在字符串中查找“单词”,然后创建一个从单词到该单词索引列表的映射,或者只对您感兴趣的关键字进行映射


如果您能提供更详细的确切情况(例如关键字、分隔符以及您需要的搜索结果),这会有所帮助。

您是否总是在寻找相同的关键字?
尝试它需要对关键字进行一些预处理,但之后会加快速度。

我为这个问题开发了一种有效的IndexOf用法:


它使用关键字列表及其在字符串中的下一个位置。这样,您只需要为每个关键字调用IndexOf一次,然后为找到的每个匹配项调用IndexOf一次。它在替换大字符串中的关键字时特别有效,因为您可以从头到尾处理字符串,而不是为每个关键字处理整个字符串一次。我不知道您为什么要在字符串中查找关键字以及如何处理字符串,但在您的情况下,它可能会很有用。

实际上我以前必须解决这个问题,这很有趣。我有20k个html页面,每个页面都有一个标题,并且希望其他页面上出现的所有其他标题都链接到具有该标题的页面。听起来很像你想要完成的

方法:

  • 通过将文件文本转换为{Word,Whitespace}的链接列表来处理文件文本,其中单词被标识为带有几个特殊字符的连续字母数字序列,空格是指向下一个单词的所有内容
  • 对我想要链接的页面的每个“标题”重复步骤1中的过程
  • 然后,将步骤1中链接列表中节点的每个单词添加到二进制排序列表中
  • 现在,您只需要从步骤2的每个标题链接列表中找到第一个单词,然后从步骤3查找二进制排序列表。当一个单词是复数时,您可能会发现几个点击,甚至是软点击,因此您可能需要测试二进制列表中的几个起始节点
  • 一旦您将文档处理成步骤1中描述的表单,实际上很容易通过插入新节点和/或修改空白值进行修改。完成后,您只需遍历整个列表并将其全部转储到流中
  • 这听起来比实际情况更复杂,它花了大约两天的时间才能正常工作


    无论你如何解决它,都要从中获得乐趣:)

    我刚刚在一个类似的帖子上发布了这篇文章,但它在这里可能更相关

    我正在做一个类似的搜索,基本上是在大约45k字节的文本中查找长度约为10-50字节的关键字。我在900万条文本中搜索了大约1900个关键词,因此尽可能快地获取这些关键词也是一个类似的优先事项

    因此,我发现使用.NET4最快的方法是并行正则表达式IsMatch

    下面是一个获取全部匹配的示例-

    needles.AsParallel ( ).Sum ( l => Regex.IsMatch ( haystack , Regex.Escape ( l ) ) ? 1 : 0 );
    
    这适用于我的场景(如上所述),在我的测试中,它比并行比较的顺序索引快55%,至少就我使用的数据大小而言。我还认为,只有在使用多核机器时,速度才会提高


    如果有人能找到更快的方法,我会感兴趣吗?

    我一直在尝试利用拉宾·卡普。问题是,所有实现都使用静态模式长度来加速算法。我无法做到这一点,当我在没有固定模式长度的情况下实现它时,计算时间会呈指数增长。哦:我搜索的文本总是长度为12286。我的模式的长度要短得多——从10到50个字符不等,并且是简单地转换成十六进制字符串的单词。(例如BitConverter.ToString(ENCODING.GetBytes(“no recoil”))我所需要的就是知道文本中是否出现了我的模式。单词前后是否总是有空格?如果是这样的话,您能在文本中的单词上进行迭代,并使用普通哈希集来检测每个单词是否为关键字吗?否。文本的格式为XX-XX-XX-XX-XX,其中每个XX是内存缓冲区中字节的十六进制表示。事实上,我可以完全不用处理字符串就解决这个问题,而是在字节数组中搜索字节。我将数据从字节[]转换为字符串(占用更多内存并有其他性能成本)的唯一原因是因为我相信字符串搜索算法比字节搜索算法更多。。。我还希望Regex能够满足我的性能要求……问题是我不知道如何使Boyer-Moore实现能够与多种模式一起工作……简单的回答是:你不能。但对于每个单独的关键字,搜索速度要快得多。这取决于关键词的数量和关键词的平均长度