【问题标题】:Runtime Trie data structure generation vs storing & reading to a file approach运行时 Trie 数据结构生成与存储和读取文件方法
【发布时间】:2020-09-30 17:42:57
【问题描述】:

我正在为英语词典中的每个单词创建一个Trie 结构。我想将此结构用于单词搜索和拼字游戏等游戏,但我不知道在运行时生成结构是否更快,或者我是否应该想办法将这个Trie 结构扁平化为JSONXML 在运行时读入内存。

我不太了解创建数据库或存储数据以供以后使用,所以任何建议都会很棒 - 现在我正在查看 JacksonJava。最终目标是将此应用程序移植到我网站上的JavaScript

【问题讨论】:

    标签: javascript json jackson hierarchical-data trie


    【解决方案1】:

    这就是您如何生成Trie 结构并在您的网站上使用它而不使用Java,只需使用JavaScript。具有两种方法的简单Trie 结构:insertsearchJS 中可能如下所示:

    function Trie() {
        this.root = new TrieNode();
        this.insert = function(key) { 
            let length = key.length, next = this.root; 
    
            for (let level = 0; level < length; level++) { 
                let character = key.charAt(level); 
                if (next.children[character] == null) {
                    next.children[character] = new TrieNode(); 
                }
    
                next = next.children[character]; 
            }
            next.endOfWord = true; 
        }
        this.search = function(key) { 
            let length = key.length, next = this.root; 
    
            for (let level = 0; level < length; level++) { 
                let character = key.charAt(level);
    
                if (next && next.children[character]) {
                    next = next.children[character];
                    continue;
                }
                return false;
            }
    
            return next && next.endOfWord;
        } 
    }
    
    function TrieNode() {
        this.children = {};
        this.endOfWord = false; 
    }
    

    使用上面的简单实现,您可以创建Trie 实例并插入您想要的所有单词:

    const trie = new Trie();
    trie.insert("hello");
    trie.insert("hi");
    trie.insert("help");
    trie.insert("helpful");
    ... more words
    

    例如,使用Node.js,您可以:

    • 从源文件中读取所有需要的单词。
    • 对于每个单词,使用insert 方法将其插入trie 结构中。
    • 从对象生成JSONJSON.stringify(trie)
    • 将其保存到一个文件:trie.js,以后可以在您的页面上使用。

    上述单词的结果 js 文件应如下所示:

    {
       "root":{
          "children":{
             "h":{
                "children":{
                   "e":{
                      "children":{
                         "l":{
                            "children":{
                               "l":{
                                  "children":{
                                     "o":{
                                        "children":{
                                           
                                        },
                                        "endOfWord":true
                                     }
                                  },
                                  "endOfWord":false
                               },
                               "p":{
                                  "children":{
                                     "f":{
                                        "children":{
                                           "u":{
                                              "children":{
                                                 "l":{
                                                    "children":{
                                                       
                                                    },
                                                    "endOfWord":true
                                                 }
                                              },
                                              "endOfWord":false
                                           }
                                        },
                                        "endOfWord":false
                                     }
                                  },
                                  "endOfWord":true
                               }
                            },
                            "endOfWord":false
                         }
                      },
                      "endOfWord":false
                   },
                   "i":{
                      "children":{
                         
                      },
                      "endOfWord":true
                   }
                },
                "endOfWord":false
             }
          },
          "endOfWord":false
       }
    }
    

    要生成有效的JS 文件,您需要在开头添加代码:const RAW_TRIE = 字符串,因此我们的文件如下所示:

    const RAW_TRIE = {
       "root":{
          "children":{
             "h":{
              ...
    

    您创建了一个原始的 Trie 对象,您可以通过将此行添加到您的 HTML 或模板文件中来将其包含到您的页面中:

    <script src="www.your-domain.com/path/to/static/file/trie.js"></script>
    

    由于加载了这个文件,您应该可以访问RAW_TRIE 对象。您可以将prototype 设置为Trie 并使用搜索方法:

    const TRIE = Object.setPrototypeOf(RAW_TRIE, new Trie());
    console.log("hello exists: " + TRIE.search("hello"));
    console.log("hello1 does not exist: " + TRIE.search("hello1"));
    

    这种方法允许您在服务器端创建包含您需要的所有单词的文件,客户端可以下载并用作常规静态文件。

    注意:上述解决方案是唯一一种方法,可以改进或更改部分(或全部)步骤。这不是最终版本 无需对生产进行任何更改即可使用。你可以尝试 优化它并通过更改使trie.js文件尽可能小 TrieNode 功能甚至删除它。

    【讨论】:

      【解决方案2】:

      以下是通过扩展原生 Map 原型创建 Trie 的方法:

      class TrieNode extends Map {
          add(word) {
              if (!word.length) return super.set("end", true);
              let child = this.get(word[0]);
              if (!child) this.set(word[0], child = new TrieNode);
              child.add(word.slice(1));
              return this; // optional: to allow chaining
          }
          has(word) {
              if (!word.length) return super.has("end");
              let child = this.get(word[0]);
              return !!child && child.has(word.slice(1));
          }
          * [Symbol.iterator]() {
              for (let [letter, child] of super.entries()) {
                  if (letter === "end") yield ""
                  else for (let word of child) yield letter + word;
              }
          }
      }
      
      // Demo
      let trie = new TrieNode;
      // Insert all words
      for (let word of ["so", "some", "somebody", "someone", "something", "son"]) {
          trie.add(word);
      }
      // For a series of strings, check whether they are in the Trie
      for (let word of Array.from("somethings", (_, i) => "somethings".slice(0, i))) {
          console.log(`"${word}" => ${trie.has(word)}`);
      }
      // List all words that are in the Trie
      for (let word of trie) console.log(word);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-01
        • 2013-01-20
        • 2013-03-26
        • 1970-01-01
        • 1970-01-01
        • 2019-05-13
        相关资源
        最近更新 更多