如何实现滑动窗口或减少这些嵌套循环?
Posted
技术标签:
【中文标题】如何实现滑动窗口或减少这些嵌套循环?【英文标题】:How to implement sliding window or reduce these nested loops? 【发布时间】:2020-03-19 00:09:36 【问题描述】:我正在尝试减少这些循环以优化一些代码。有人建议我使用滑动窗口技术,但我似乎无法让它适合我的示例。
我添加括号中的所有内容只是为了显示它们是什么类型。 file.get(..) 方法从文件中的给定索引返回一个字节。外部循环可以(通常)迭代一个巨大的范围,因为这些文件非常大。 asciiCombo 包含 2-8 个元素。
这是一个嵌套循环,我不确定如何减少:
for (long i = offsetInBytes; i < (long) file.length; ++i)
int match = 0;
for (int j = 0; j < (int[]) asciiCombo.length; ++j)
if (file.get(i + j) == asciiCombo[j])
match++;
else
break;
用 if 语句或一些要查找的集合替换内部循环与嵌套循环基本相同,因此不会这样做。我一直无法实现滑动窗口(甚至不确定是否可以)。
我在这里遇到了一个卡住的地方,希望能提供任何帮助。谢谢!
【问题讨论】:
【参考方案1】:这是一个字符串搜索问题。
有一种有效的滑动窗口技术,称为 Rabin-Karp 算法:https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
它需要一个“特殊的”哈希函数,允许您在滑动窗口前进时快速更新其哈希值。我将“special”放在引号中,因为最常见的字符串散列方法——多项式散列——确实有效。
但是,有很多选择。我喜欢 Knuth-Morris-Pratt:https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
它会为您正在搜索的字符串计算一个状态机,该状态机允许对文件中的每个字节进行一次准确的检查。
Boyer-Moore 也很受欢迎:https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm
但是,请注意,根据我对您的代码的了解,以及您要查找的字符串通常只有 2-8 个字节长的声明,我认为您选择的搜索算法不会是问题所在.在我看来,您对 file.get(index)
的实施很慢。
您可能想改用BufferedInputStream(FileInputStream(...))
。这将按顺序为您提供一个字节。使用适用于此限制的字符串搜索。 Knuth-Morris-Pratt 会很好,或者如果字符串真的被限制为 8 个字节,那么整个事情都适合 long
。使用它直接将所有 8 个字符与文件中的前 8 个字符与一个 ==
进行比较。
【讨论】:
以上是关于如何实现滑动窗口或减少这些嵌套循环?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PySpark 进行嵌套的 for-each 循环