如何实现滑动窗口或减少这些嵌套循环?

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 个字符与一个 == 进行比较。

【讨论】:

以上是关于如何实现滑动窗口或减少这些嵌套循环?的主要内容,如果未能解决你的问题,请参考以下文章

算法和数据结构解析-5 : 滑动窗口问题

算法和数据结构解析-5 : 滑动窗口问题

如何减少python中嵌套循环的时间

如何使用 PySpark 进行嵌套的 for-each 循环

使用具有多个参数和索引的lapply / sapply减少函数内的嵌套循环

Tkinter 嵌套主循环