[英]Given a string S and a string T, count the number of distinct subsequences of T in S
[英]Given a string s and an array of smaller strings, T, how to design a method to search s for each small string in T?
给定一个字符串s和一个较小字符串数组T,设计一种方法来搜索s中T中的每个小字符串。
谢谢。
假设你有大量较小的字符串, Rabin-Karp是在非常大的字符串中搜索多个小字符串的标准方法。 如果你只有一些较小的字符串,只需重复一个Boyer-Moore ,这可能是一个更好的选择。
我所知道的解决这个问题的最快方法是Aho-Corasick算法 。 对于要搜索的大字符串和大量模式,它比为每个模式应用线性时间搜索(例如KMP,Rabin-Karp,Boyer-Moore)更快。
但是你确定你需要这样的东西,你的字符串太长了,不能直接进行字符串匹配吗?
如果不了解有关数据集的更多详细信息,则无法选择“最佳”算法。
没有这些信息,“最佳”解决方案是最简单的解决方案。
static IEnumerable<string> FindIn(this IEnumerable<string> T, string s) {
return T.Where(t => s.Contains(t));
}
你能澄清一下吗?
**算法将强烈取决于“搜索”的含义。 **
你想知道T中的每个字符串是否是S的正确子字符串? 还是任何字符串?
您需要是/否答案还是索引?
您是否关心答案是否重叠(例如“ABCDE”包含“ABC”和“CDE”,但仅在您不关心重叠时)。
一种简单的方法(假设搜索字符串都以相当不同的方式开始)是:
有一个“第一个字符”=> map_of_first_2_characters__to__list_of_strings的地图。
循环遍历S中的每个位置,在上面的地图中找到该字符作为键。
该值将是另一个映射,将2个字符的字符串映射到以这2个字符开头的子字符串列表。
在子图中查找字符及其右邻居,该值将是以这两个值开头的字符串列表。
假设T和T中的起始字符分布相当均匀(如果它太大,仅仅通过映射3个字符来构建数据结构一层) - 我们刚刚找到了一个非常短的合理匹配列表,从当前开始位置。 字符串 - 比较它们。 标记从当前位置开始的S的子串(如果有的话)。 如果目标不是找到所有字符串的所有匹配项,则从数据结构中删除您找到的匹配项。
您可能希望阅读此内容以获取高级内容
让我们把它变成一个Java解决方案
boolean isSubset(String[] t, String s) {
for (String sample: t)
if (!sample.equals(s))
return false;
return true;
}
你可以使用Falaina的建议加快速度,但你真的需要吗?
如果你有一个指针表空间(指针大小* NumCharsInSource),你可以使用像QSort这样的东西对源中的每个字符串(字符串开头的字符串)进行排序。 然后,您可以将较小的字符串BSearch到指针表中。 假设N个字符和M个子串,排序将具有O(N lg N)性能,并且查找将具有O(M lg N)性能。 总体性能应为O((N + M)lg N)。
但是,可能存在退化情况,其中源中的字符串是高度重复的(即100,000个a后跟ab)。 这将使排序部分的比较非常缓慢:-(为了解决这个问题,你可以特殊情况下长时间运行字符,但这会变得更加复杂。
选择的算法实际上取决于您的源数据以及您必须使用多少备用内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.