【问题标题】:Fast and efficient algorithm for Phrases Dictionary lookup?快速高效的短语字典查找算法?
【发布时间】:2011-09-09 16:53:14
【问题描述】:

假设我有一本包含几百万个单词和短语的字典。对于每个输入句子,我想识别(完全匹配)字典包含的所有单词/短语。应该首选最长的字典名称,并且没有重叠。 例如:

Sentence: "Los Angeles Lakers visited Washington State last week"
Dictionary: {Los Angeles, Lakers, Los Angeles Lakers, Washington, State, Washington State University}

Then the sentence would be tagged as follows:
[Los Angeles Lakers] visited [Washington] [State] last week. 

我能想到的一个解决方案是将字典以恒定的查找时间(例如,基于散列的集合)存储在内存中,然后从每个句子中提取所有单词 n-gram(n 可以设置为字典中最长的短语)将每个短语与字典进行比较并保留最长的不重叠的短语。有更好的解决方案吗? (因为 n-gram 的生成可能很慢)。也许树木可以提供帮助?

谢谢!

【问题讨论】:

  • 所以你决定选择洛杉矶湖人队而不是洛杉矶队,因为时间更长。但是是什么让某些东西变得更长——字母或单词?考虑“蓝天太棒了”,你有 4 个词和 15 个字符的“蓝天是”,或者只有 3 个词但 19 个字符的“天空太棒了”。哪个会赢?
  • 如果单词数量相等,那么您将使用什么标准。字符更长?标记中最长的单词(例如,“A Rocket”会胜过“This guy”)?
  • 如果是平局,我不在乎谁会赢。甚至是随机作品。

标签: java search tree lookup


【解决方案1】:

您可能需要考虑使用 radix treeprefix tree 之类的东西,将整个单词用作构建的一部分。这些是字典类型问题很自然的树。

然后简单地将事物拆分为单词,并执行对 trie 的搜索。根据分组的预期长度,您可以从前面构建(不情愿)或从后面构建(贪婪)。

【讨论】:

  • 这可能比 DAWG 还要好。虽然需要更多空间,但它看起来更容易处理空白。您能否进一步详细说明正面和背面之间的区别?非常感谢!
  • 就像你在解析时从前面或后面抓取单词:Los -> Los Angeles -> Los Angeles Lakers 从后面将是 Los Angeles Lakers visited Washington State last week -> Los Angeles Lakers visited Washington State last -> Los Angeles Lakers visited Washington State -> etc.. 本质上我是在谈论如何解析语句以将组聚集在一起。
【解决方案2】:

您可以查看DAWG (Directed acyclic word graph)。您可以将整个短语作为路径存储在 DAWG 中。然后,您将开始匹配句子并找到匹配的最长短语作为最长路径。然后,您将类似地继续处理其余不匹配的句子。空白需要一些特殊处理。

【讨论】:

  • @glowcoder DAWG 是个好主意;非常节省空间。但是假设我有一个句子“洛杉矶州立大学”,而字典只有两个短语 {State University, University of Los Angeles}。从一开始的匹配会将句子标记为:“[State University] of Los Angeles”而不是“State [University of Los Angeles]”。所以我需要考虑一下。谢谢!
  • 所以也许我应该在每次匹配后只从句子中删除一个单词,而不是删除迄今为止匹配的最长字符串。我认为这就是 Steven Goldade 在他的回答中所指的。
【解决方案3】:

以下代码执行句子的非重叠标记,优先考虑较长的匹配项。

它将句子视为字符串标记的数组。

它使用“max_key_size”参数(字典中键的最大大小)来避免搜索永远不会发生的匹配。 在您的示例中,生成的句子是:

[[洛杉矶湖人队],访问,[华盛顿],[州],上周]

希望对你有帮助:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class NonOverlappingTagging {

    private static ArrayList non_overlapping_tagging(String[] sentence, HashMap dict,int max_key_size) {
        ArrayList tag_sentence = new ArrayList();
        int N = sentence.length;

        if (max_key_size == -1) {
            max_key_size = N;
        }

        int i = 0;

        while (i < N) {

            boolean tagged = false;
            int j = Math.min(i + max_key_size, N); //avoid overflow

            while (j > i) {
                String[] literal_tokens = Arrays.copyOfRange(sentence, i, j);
                String literal = join(literal_tokens, " ");
                System.out.println(literal);

                if (dict.get(literal) != null) {
                    tag_sentence.add("["+literal+"]");
                    i = j;
                    tagged = true;
                }
                else {
                    j -= 1;
                }

            }

            if (!tagged) {
                tag_sentence.add(sentence[i]);
                i += 1;
            }
        }

        return tag_sentence;
    }

    private static String join(String[] sentence, String separator) {
        String result = "";
        for (int i = 0; i < sentence.length; i++) {
            String word = sentence[i];
            result += word + separator;
        }

        return result.trim();
    }

    public static void main(String[] args) {
        String[] sentence = {"Los", "Angeles", "Lakers", "visited", "Washington", "State", "last", "week"};
        HashMap <String, Integer>dict = new HashMap();
        dict.put("Los Angeles", 1);
        dict.put("Lakers", 1);
        dict.put("Los Angeles Lakers", 1);
        dict.put("Washington", 1);
        dict.put("State", 1);
        dict.put("Washington State University", 1);

        ArrayList tagging = non_overlapping_tagging(sentence, dict, -1);

        System.out.println(tagging);    
    }   
}

【讨论】:

    猜你喜欢
    • 2016-11-15
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2012-01-18
    • 1970-01-01
    相关资源
    最近更新 更多