• [Algorithm] Search for matching words


    Implement an autocomplete system. That is, given a query string s and a set of all possible query strings, return all strings in the set that have s as a prefix.

    For example, given the query string de and the set of strings [dogdeerdeal], return [deerdeal].

    Hint: Try preprocessing the dictionary into a more efficient data structure to speed up queries.

    It is using the Trie data stucture, check thist post;

    The only changes is that when we search for words, it is partially matched + whole word match.

    Which means if we search 'de', it should return [deer, deal],

    if we search 'deer', it should return [deer],

    if we search 'deerr', it should return [].

    function Node () {
      return {
        keys: new Map(),
        isEnd: false
      }
    }
    
    function Trie () {
      return {
        root: new Node(),
        // Add words into the tree
        // Recursive
        add(word, node = this.root) {
          // If there is no word, means it reach the end
          if (word.length === 0) {
            node.isEnd = true;
            return;
          }
          
          const [head, ...rest] = word;
          // If char is not set, then create a new Node to hold char
          // Otherwise, continue
          if (!node.keys.has(head)) {
            node.keys.set(head, new Node(head));
          }
          // Continue with three
          this.add(rest, node.keys.get(head));
        },
        // Print all the words in the tree
        print () {
          let words = [];
          // Helper function, Recursive
          function search (node = this.root, string = '') {
            // Make sure we have keys
            if (node.keys.size !== 0) {
              for (let key of node.keys.keys()) {
                // update node, update string
                search(node.keys.get(key), string.concat(key));
              }
              // if reach the end, push to the words
              if (node.isEnd) {
                words.push(string);
              }
            } else {
              // If there is no keys, then push the avaialbe string to the words
              string.length > 0 ? words.push(string) : null;
            }
          }
          
          search(this.root, '');
          return words.length > 0 ? words : null; 
        },
        // Find the words based on input
        find (input) {
          let words = [];
          
          function search(node = this.root, string = '', input) {
            
            if (node.keys.size !== 0) {
              for (let key of node.keys.keys()) {
                // if the key is the same as input[0]
                // becasue we want the whole word, so continue with current trees
                if (key === input[0] || input.length === 0) {
                  let rest = input.length === 0 ? '': input.substr(1);
                  search(node.keys.get(key), string.concat(key), rest);
                } 
              }
            } else {
              // In case of input is 'cattt', then return undefined
              if (input.length !== 0) {
                return [];
              }
              string.length > 0 ? words.push(string) : [];
            }
          }
          
          search(this.root, '', input);
          
          return words.length > 0 ? words : [];
        }
      }
    }
    
    function searchWords () {
      const data = ['dog', 'dollar', 'cat', 'drag'];
      const trie = new Trie();
      
      data.forEach(d => trie.add(d));
      console.log(trie.find('do')); // [ 'dog', 'dollar' ]
      console.log(trie.print()); // [ 'dog', 'dollar', 'drag', 'cat' ]
    }
    
    searchWords();
  • 相关阅读:
    表优化
    存储和压缩
    自定义函数
    Hadoop中SecondaryNameNode和HA(高可用)区别
    ASUS笔记本,更换了固态硬盘,重装系统前后开机都自动进入BIOS界面
    顶部下拉菜单制作笔记
    综合笔记
    工具sublime安装
    head引入样式
    滚动固定导航代码
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10548079.html
Copyright © 2020-2023  润新知