【问题标题】:Find substring in many objects containing multiple strings在包含多个字符串的许多对象中查找子字符串
【发布时间】:2012-08-10 13:06:12
【问题描述】:

我正在处理一组对象,其合理大小可能在 1 到 50K 之间(但没有设定上限)。每个对象都包含一些字符串。

我想实现一个搜索函数,它可以部分、完全或正则表达式匹配这些字符串中的任何一个,然后返回一个对象列表。

如果每个对象只包含一个字符串,那么我可以简单地按字典顺序对它们进行排序,并相当容易地提取范围 - 但由于速度/内存的原因,我不愿意为每个包含的字符串实现 map 类结构担心。

是否有一种数据结构非常适合这种操作以提高速度和内存效率?我感觉到一个数据库可能即将出现,但我对它们知之甚少,所以我想推迟研究,直到有更多知识渊博的人能够将我推向正确的方向!

【问题讨论】:

    标签: c++ string qt data-structures


    【解决方案1】:

    类似地图的集合可能是您最好的选择,键是字符串,值是对包含对象的引用。如果您的字符串作为 stl 字符串保存在对象中,那么您可以将数据的引用存储在映射的关键部分中(或者使用 shared_ptr 作为字符串并在对象和映射中引用它们)

    搜索、排序只是实现一个使用取消引用数据的custom search functor 的问题。地图的大小将是 2 个引用加上地图开销,如果您考虑到替代方案将同样大,即使不是更大,也不会那么糟糕。

    【讨论】:

      【解决方案2】:

      部分、完全或正则表达式匹配这些字符串中的任何一个,然后返回一个对象列表

      好吧,对于完全匹配,您可以使用std::map<std::string, std::vector<object*> >。键是确切的字符串,vector 保存指向匹配对象的指针,其中许多指针可能指向单个对象实例。

      你可以有一个从部分字符串到完整字符串的前端映射:假设字符串是“dogged”,很遗憾你不得不为“dogged”、“ogged”、“gged”、“ged”输入条目"、"ed" 和 "d"(如果您想要最小匹配大小,请在任何地方停止)...然后使用 lower_bound 进行搜索。这样,假设您搜索“dog”,您仍然可以看到“dogged”的匹配项(是否匹配说“dogfood”并不重要。这将是一个简单的std::map<string, string>。当你增加转发时从 lower_bound 位置和字符串仍然匹配(即从 dogfood 到 dogged to ... 直到它不以 dog 开头),您可以在“精确匹配”映射中搜索并汇总结果。

      对于正则表达式,我没有什么好的建议...我会从蛮力搜索所有完整字符串开始。如果它确实不够好,那么您可以进行一些粗略的优化,例如在进行蛮力匹配之前检查要过滤的常量子字符串,但我无法想象如何非常彻底和快速地做到这一点。

      (如果有用的话,用你最喜欢的智能指针替换object*s)

      【讨论】:

        【解决方案3】:

        感谢所有回复,但在此post 中提到的技术之后,我决定使用来自仅标头SeqAn 项目的增强后缀数组。

        【讨论】:

          猜你喜欢
          • 2016-10-18
          • 2014-06-25
          • 2017-02-12
          • 2021-09-30
          • 2013-02-05
          • 1970-01-01
          • 1970-01-01
          • 2021-08-15
          • 1970-01-01
          相关资源
          最近更新 更多