【问题标题】:Best algorithm to index sentences索引句子的最佳算法
【发布时间】:2010-10-18 05:48:20
【问题描述】:

想象一下,我需要为句子编制索引。让我更深入地解释一下。

例如我有这些句子:

  1. 美丽的天空。
  2. 美丽的天空之梦。
  3. 美丽的梦想。

据我想象,索引应该是这样的:

alt text http://img7.imageshack.us/img7/4029/indexarb.png

但我也想通过这些词中的任何一个进行搜索。

例如,如果我通过“the”进行搜索,它应该显示给我与“beautiful”的联系。 如果我通过“美丽”进行搜索,它应该给我与(上一个)“The”、(下一个)“天空”和“梦想”的联系。如果我按“天空”搜索,它应该(以前)连接到“美丽”等......

有什么想法吗?也许您知道针对此类问题的现有算法?

【问题讨论】:

  • 使用关联数组可以让您在 Perl 中快速解析句子。它比您预期的要快得多,并且可以有效地将其转储到树状结构中,以供更高级别的语言随后使用。不过你想要一个算法。
  • @Lukas Šalkauskas,你为什么要删除这个问题?这很棒。图中只有一个错字。

标签: algorithm search indexing seo


【解决方案1】:

简答

用两个前向/前向链接向量创建一个结构。 然后将单词结构存储在哈希表中,键作为单词本身。

长答案

这是一个不容易解决的语言解析问题,除非您不介意胡言乱语。

  1. 我去了公园篮球场。
  2. 你能把车停好。

您的链接算法将创建如下句子:

  1. 我开车去了公园。
  2. 你能把篮球场停好。

我不太确定这方面的 SEO 应用程序,但我不欢迎另一个乱七八糟的垃圾邮件网站占用搜索结果。

【讨论】:

    【解决方案2】:

    我想你会想要某种Inverted index 结构。您将拥有一个 Hashmap,其中单词作为键指向 (sentence_id, position) 形式的对列表。然后,您可以将句子存储为数组或链表。您的示例如下所示:

    sentence[0] = ['the','beautiful', 'sky'];
    sentence[1] = ['beautiful','sky', 'dream'];
    sentence[2] = ['beautiful', 'dream'];
    
    inverted_index = 
    {
     'the': {(0,0)},
     'beautiful': {(0,1), (1,0), (2,0)},
     'sky' : {(0,2),(1,1)},
     'dream':{(1,2), (2,1)}
    };
    

    使用这种结构查找单词可以在恒定时间内完成。识别出您想要的单词后,还可以在恒定时间内找到给定句子中的前一个和后一个单词。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您可以尝试挖掘由句子组成的Markov chains。您还需要双向链(即查找下一个和上一个单词),即存储可能出现在给定之后或之前的单词。

      当然,马尔可夫链是一个随机生成内容的过程,但是也可以使用类似的方法来存储您需要的信息。

      【讨论】:

      • 为什么这被否决了?这就是商业应用程序在进行单词预测和解析时的工作方式。
      • 因为当询问者想要确定性索引时它的概率索引。此外,马尔可夫链只擅长预测简单的受限语音,而其他方面则不多。
      【解决方案4】:

      看起来它可以存储在一个非常简单的数据库中,包含以下表格:

      Words:
          Id     integer primary-key
          Word   varchar(20)
      Following:
          WordId1 integer foreign-key Words(Id) indexed
          WordId2 integer foreign-key Words(Id) indexed
      

      然后,每当你解析一个句子时,只需插入那些不存在的句子,如下所示:

      The beautiful sky.
          Words (1,'the')
          Words (2, 'beautiful')
          Words (3,, 'sky')
          Following (1, 2)
          Following (2, 3)
      Beautiful sky dream.
          Words (4, 'dream')
          Following (3, 4)
      Beautiful dream.
          Following (2, 4)
      

      然后你可以随心所欲地查询其他单词之后或之前的单词。

      【讨论】:

        【解决方案5】:

        这应该让你接近,在 C# 中:

        class Program
        {
            public class Node
            {
                private string _term;
                private Dictionary<string, KeyValuePair<Node, Node>> _related = new Dictionary<string, KeyValuePair<Node, Node>>();
        
                public Node(string term)
                {
                    _term = term;
                }
        
                public void Add(string phrase, Node previous, string [] phraseRemainder, Dictionary<string,Node> existing)
                {
                    Node next= null;
                    if (phraseRemainder.Length > 0)
                    {
                        if (!existing.TryGetValue(phraseRemainder[0], out next))
                        {
                            existing[phraseRemainder[0]] = next = new Node(phraseRemainder[0]);
                        }
                        next.Add(phrase, this, phraseRemainder.Skip(1).ToArray(), existing);
                    }
                    _related.Add(phrase, new KeyValuePair<Node, Node>(previous, next));
        
                }
            }
        
        
            static void Main(string[] args)
            {
                string [] sentences = 
                    new string [] { 
                        "The beautiful sky",
                        "Beautiful sky dream",
                        "beautiful dream"
                    };
        
                Dictionary<string, Node> parsedSentences = new Dictionary<string,Node>();
        
                foreach(string sentence in sentences)
                {
                    string [] words = sentence.ToLowerInvariant().Split(' ');
                    Node startNode;
                    if (!parsedSentences.TryGetValue(words[0],out startNode))
                    {
                        parsedSentences[words[0]] = startNode = new Node(words[0]);
                    }
                    if (words.Length > 1)
                        startNode.Add(sentence,null,words.Skip(1).ToArray(),parsedSentences);
                }
            }
        }
        

        我冒昧地假设您想保留实际的初始短语。最后,您将获得短语中的单词列表,并且在每个短语中,都有一个使用该单词的短语列表,并引用每个短语中的下一个和上一个单词。

        【讨论】:

          【解决方案6】:

          使用associative array 可以让您在 Perl 中快速解析句子。它比您预期的要快得多,并且可以有效地将其转储到树状结构中,以供更高级别的语言后续使用。

          【讨论】:

            【解决方案7】:

            树搜索算法(如 BST 等)

            【讨论】:

            • 是的,不是。一点也不。
            猜你喜欢
            • 2017-05-09
            • 2017-02-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-27
            • 1970-01-01
            • 2016-03-19
            • 1970-01-01
            相关资源
            最近更新 更多