【问题标题】:Trie with association between words尝试单词之间的关联
【发布时间】:2016-05-26 17:46:36
【问题描述】:

我有一个用例,我想纠正单词。 我有一组正确和不正确的单词[拼写错误]。 我用所有单词填充树。 我有每个单词的正确和错误版本。

现在,如果我得到“a”这个词来进行更正,

-- 我在 trie 中搜索它。如果 trie 有这个词,我想将这个词与这个词的正确版本相关联。

解决方案: 我可以在 trie 中不正确单词的最后一个节点设置单词的正确版本 ["a1"]。并且可以将其解析为“a1”。

但我必须在最后一个节点存储每个单词的正确版本,这会增加内存占用。 因为我已经加载了所有单词来尝试 [正确/不正确]。 有什么方法可以在正确和不正确的单词之间建立关联,而无需再次将整个单词作为值存储在最后一个节点中? 有指针吗?

public class TrieNode<T> {

    private Map<Character, TrieNode<T>> childs;
    private boolean complete;
    private T value;

    ....
    }

【问题讨论】:

  • 如何存储对父节点的引用?这样,您可以从错误的拼写指向正确拼写的最后一个节点,并以相反的顺序恢复结果字符串。
  • 这是个好主意。唯一的问题是它可能会增加内存占用,但这是一个好技巧。

标签: algorithm nlp trie


【解决方案1】:

您可以为此使用单个字典。在 C# 中,这将是:

Dictionary<string, string> MisspellingsLookup = new Dictionary<string, int>();

key是拼写错误,value是正确的拼写。

现在,有些单词通常以多种方式拼写错误。例如,“occasion”经常被拼错为“ocassion”或“occassion”,如果想减少多个拼写错误占用的内存,可以在构建时使用临时字典。每当您添加拼写错误时,您都会在好词词典中查找正确的拼写,如果它已经存在,则使用该值。因此,您所做的只是存储对现有单词的引用,而不是创建新字符串。这是一个例子:

Dictionary<string, string> GoodWords = new Dictionary<string, int>();
Dictionary<string, string> Misspellings = new Dictionary<string, string>();

void AddMisspelling(string misspelled, string correct)
{
    string goodWord;
    if (!GoodWords.TryGetValue(correct, out goodWord))
    {
        goodWord = correct;
        GoodWords.Add(correct, correct);
    }

    // Always use goodWord here, so you're not creating duplicate strings.
    Misspellings.Add(misspelled, goodWord);
}

添加完单词后,您可以清除GoodWords 字典以节省空间:

GoodWords = null;

我在这里推荐一个字典,因为它几乎肯定会使用更少的内存,并且查找是 O(1) 而不是 O(word length)。

【讨论】:

    猜你喜欢
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多