Java中基本滑动窗口算法的实现

时间:2013-09-11 15:52:49

标签: java algorithm

我试图在Java中实现以下基本滑动窗口算法。我得到了它的基本概念,但我对一些措辞有点困惑,特别是粗体句子:

固定宽度为w的滑动窗口在文件中移动, 并且在文件中的每个位置k,都是指纹 它的内容是计算出来的设k为块边界 (即,Fk mod n = 0)。 而不是哈希的哈希 整个块,我们选择数字最小的指纹 这个块中的滑动窗口。然后我们计算一个哈希 在块中随机选择的窗口。直观地说, 这种方法允许在块内进行小的编辑 对相似度计算的影响较小。这种方法 生成一个可变长度的文档签名,其中 签名中的指纹数量与之成正比 文件长度。

请参阅下面的我的代码/结果。我理解算法的基本思想吗?根据粗体文本,“在其块中选择数量最小的滑动窗口指纹”意味着什么?我目前只是对整个块进行散列。

    public class BSW {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int w = 15; // fixed width of sliding window
        char[] chars = "Once upon a time there lived in a certain village a little             
            country girl, the prettiest creature who was ever seen. Her mother was 
            excessively fond of her; and her grandmother doted on her still more. This 
            good woman had a little red riding hood made for her. It suited the girl so 
            extremely well that everybody called her Little Red Riding Hood."
                .toCharArray();

        List<String> fingerprints = new ArrayList<String>();

        for (int i = 0; i < chars.length; i = i + w) {

            StringBuffer sb = new StringBuffer();

            if (i + w < chars.length) {
                sb.append(chars, i, w);
                System.out.println(i + ". " + sb.toString());
            } else {
                sb.append(chars, i, chars.length - i);
                System.out.println(i + ". " + sb.toString());
            }

            fingerprints.add(hash(sb));

        }

    }

    private static String hash(StringBuffer sb) {
        // Implement hash (MD5)
        return sb.toString();
    }

}

结果:

0. Once upon a tim
15. e there lived i
30. n a certain vil
45. lage a little c
60. ountry girl, th
75. e prettiest cre
90. ature who was e
105. ver seen. Her m
120. other was exces
135. sively fond of 
150. her; and her gr
165. andmother doted
180.  on her still m
195. ore. This good 
210. woman had a lit
225. tle red riding 
240. hood made for h
255. er. It suited t
270. he girl so extr
285. emely well that
300.  everybody call
315. ed her Little R
330. ed Riding Hood.

3 个答案:

答案 0 :(得分:2)

这不是一个滑动窗口。你所做的就是将输入分解成不相交的块。滑动窗口的一个例子是

Once upon a time
upon a time there
a time there lived
etc. 

答案 1 :(得分:1)

根据我的理解,简单的答案是否定的(我曾在多年前研究滑动窗口算法,所以我只记得原理,但不记得一些细节。如果你有更深刻的理解,请纠正我。)

作为算法“滑动窗口”的名称,您的窗口应该滑动而不是像

那样跳跃
at every position k in the file, the fingerprint of its content is computed

在你的报价中。也就是说,窗口每次都会滑动一个字符。

据我所知,应该区分块和窗口的概念。所以应该是指纹和哈希,虽然它们可能是相同的。鉴于计算哈希作为指纹的费用太高,我认为Rabin fingerprint是一个更合适的选择。块是文档中的大块文本,窗口突出显示块中的一小部分。 IIRC,滑动窗口算法的工作原理如下:

  1. 首先将文本文件分块;
  2. 对于每个块,您可以滑动窗口(运行中的15个字符块)并为每个文本窗口计算其指纹;
  3. 你现在拥有了块的指纹,其长度与块的长度成正比。
  4. 接下来是您如何使用指纹来计算不同文档之间的相似性,这是我所不知道的。能否请您指出您在OP中提到的文章的指针。作为交换,我向您推荐本文,它引入了滑动窗口算法的方差来计算文档相似度。

    Winnowing: local algorithms for document fingerprinting

    您可以参考的另一个应用程序是rsync,它是一个具有块级(对应于您的块)重复数据删除的数据同步工具。请参阅how it works的简短文章。

答案 2 :(得分:0)

package com.perturbation;

import java.util.ArrayList;
import java.util.List;

public class BSW {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int w = 2; // fixed width of sliding window
        char[] chars = "umang shukla"
                .toCharArray();

        List<String> fingerprints = new ArrayList<String>();

        for (int i = 0; i < chars.length+w; i++) {

            StringBuffer sb = new StringBuffer();

            if (i + w < chars.length) {
                sb.append(chars, i, w);
                System.out.println(i + ". " + sb.toString());
            } else {
                sb.append(chars, i, chars.length - i);
                System.out.println(i + ". " + sb.toString());
            }

            fingerprints.add(hash(sb));

        }

    }

    private static String hash(StringBuffer sb) {
        // Implement hash (MD5)
        return sb.toString();
    }

}

这个程序可以帮到你。请尽量提高效率