1

所以我有一个文档和一个指定的 n-gram 目标字符串。我正在尝试查找所有出现的目标字符串的索引。

final Pattern WORD_PATTERN = Pattern.compile("\\w+");
Matcher matcher = WORD_PATTERN.matcher("the lazy dog, jumps, the lazy dog.");

所以字符串是“the lazy dog, jumps, the lazy dog”。

假设我的目标 n-gram 是“懒惰的”。我基本上按如下方式“迭代”整个字符串,将“n”个单词添加到链表 currentNGram。如果 currentNGram 中的所有单词都与目标 n-gram 匹配,我会保存索引。否则,我删除链表的第一个元素,并附加到输入字符串中的下一个单词(例如,检查文档中的下一个连续 n-gram)。

while (matcher.find()) {
    while (currentNGram.size() < lengthOfTargetNTuple) { 
        currentNGram.add(matcher.group().toLowerCase());
            System.out.println(currentNGram.getLast());
    }
}

所以这一切都很好,但我的下一个问题是我必须再次“迭代”文档,并找到每个 n-gram 到最近的目标 n-gram 的距离。所以我采取完全相同的方法。除了这一次,当我重新初始化匹配器并按如下方式运行循环时,

 while (matcher.find()) {
        while (currentGram.size() < lengthOfTargetNTuple) {
            currentGram.add(matcher.group().toLowerCase());
                    System.out.println(currentGram.printLast()) // Psuedocode
        }

它打印单词“the”7次而不是打印“the”“lazy”“dog”“jumps”等。但是,

while (matcher.find()) {
        while (currentGram.size() < lengthOfTargetNTuple) {
            currentGram.add(matcher.group().toLowerCase());
        }
        System.out.println(matcher.group()); // Prints words in order, correctly
}

为什么是这样?为什么 matcher.group() 方法在第一个问题中以正确的顺序调用打印出的单词,而不是第二个问题?任何方向将不胜感激;我知道这是一个很长的帖子,对不起。

谢谢!

4

1 回答 1

1

首先,一些基础知识。让我们看看有什么Matcher.find...

尝试查找与模式匹配的输入序列的下一个子序列。此方法在此匹配器区域的开头开始,或者,如果该方法的先前调用成功并且匹配器此后尚未重置,则从前一个匹配不匹配的第一个字符开始。

接下来我们一起来看看Matcher.group

返回与前一个匹配项匹配的输入子序列。


现在我们了解了它们的工作原理,让我们看看下面的循环做了什么。

while (matcher.find()) {
    while (currentGram.size() < lengthOfTargetNTuple) {
        currentGram.add(matcher.group().toLowerCase());
                System.out.println(currentGram.printLast()) // Psuedocode
    }
}

currentGram.printLast每次通话都要打印几次matcher.find——准确地说,是lengthOfTargetNTuple多次。currentGram.printLast必须导致刚刚添加的内容 - matcher.group().toLowerCase()。因为我们只matcher.find为整个循环调用了一次,所以这个值不会改变。

while (matcher.find()) {
    while (currentGram.size() < lengthOfTargetNTuple) {
        currentGram.add(matcher.group().toLowerCase());
    }
    System.out.println(matcher.group()); // Prints words in order, correctly
}

但是,在这里,您每次调用matcher.group只打印一次。match.find这意味着您只打印每个匹配的子序列一次,而不是lengthOfTargetNTuple多次。

于 2012-09-15T07:37:48.663 回答