-1

我正在研究源代码剽窃算法(风选算法)的实现,并且遇到了需要帮助的问题。

示例:我有一个字符串

String test="blahello,,,,/blatestbla7234///§"§$%"%$\n\n23344)§()(§$blablayeahbla";

并将此字符串转换为

test="blahelloblatestblablablayeahbla"

并从这个字符串中构建公斤,例如 5 克

blahe  lahel  ahell hello  ellob  llobl .... ahbla

我将 kgrams 保存在字符串列表中,但也想从每个 kgram 的原始文本中保存开始和结束位置,因此我可以在最后将每个 kgram 引用回其原始文本位置。

编辑:

所以我的问题是我怎样才能得到一公斤的开始和结束位置有人能帮我吗?你有什么主意吗?提前致谢。

4

1 回答 1

0

如果您想要原始字符串中的位置,则不能先删除非字母,否则信息会丢失。您要么需要直接在原始字符串中查找 kgram(更多 CPU 时间),要么将每个字母的原始位置与修改后的字符串一起存储(更多内存空间)。

这是后者的实现:

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

public class KGram {

    public final String str;
    public final int start;
    public final int end;

    public KGram(String str, int start, int end) {
        this.str = str;
        this.start = start;
        this.end = end;
    }

    @Override
    public String toString() {
        return "KGram[\"" + str + "\":" + start + "," + end + "]";
    }

    public static List<KGram> extractFrom(String input, int size) {
        char[] chars = new char[input.length()];
        int[] indexes = new int[input.length()];
        int len = 0;

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (!Character.isLetter(c)) continue;

            chars[len] = c;
            indexes[len] = i;
            len++;
        }

        List<KGram> kgrams = new ArrayList<>();
        for (int i = 0, j = size - 1; j < len; i++, j++) {
            String str = new String(Arrays.copyOfRange(chars, i, j + 1));
            kgrams.add(new KGram(str, indexes[i], indexes[j]));
        }
        return kgrams;
    }
}

例子:

String test = "blahello,,,,/blatestbla7234///§\"§$%\"%$\n\n23344)§()(§$blablayeahbla";
List<KGram> kgrams = KGram.extractFrom(test, 5);

System.out.println(kgrams.get(4));  // prints KGram["ellob":4,13]
System.out.println(kgrams.get(26)); // prints KGram["ahbla":60,64]
于 2017-05-09T21:34:06.323 回答