在输入中使用搜索时如何保存上次搜索?

时间:2019-04-25 19:52:25

标签: javascript algorithm search

我正在尝试编写一种算法,用于保存最近搜索的关键字。问题是用户不会触发搜索,而是每次键入内容时都会触发搜索。目前,我正在尝试保存上一个搜索到的关键字,并检查下一个关键字是否以最后一个关键字开头,以便丢弃最后一个关键字。

async _persistSearch(term) {
        const serachLog = await this._getLastSearchedFile()
        console.log("[SEARCH]", serachLog);
        if (Object.keys(serachLog) == 0) {
            serachLog.searches = [term];
            serachLog.lastUpdated = Date.now()
        } else if (term.startsWith(this.lastSearhed)) {
            const toPersist = serachLog.searches.filter((value) => value != this.lastSearhed).push(term);
            serachLog.searches = toPersist;
        } else {
            serachLog.searches.push(term);
        }
        this.lastSearhed = term;
        await writeJSONFile(this.searchesFile, serachLog);
    }

例如输入[so,som,some,somet,somethi,somethi,somethin,somethin,thin]成为[something]

1 个答案:

答案 0 :(得分:0)

您应该使用Trie(前缀树)保存搜索到的关键字。假设您只处理小写英文字母,那么每个节点最多可以有26个子节点。对于每个新的搜索关键字,请调用startsWith方法以检查此新关键字是否为先前关键字的任何前缀。

如果需要有关为何在您的情况下使用Trie的更多说明,请阅读此https://en.wikipedia.org/wiki/Trie

此数据结构的Java实现如下。

class Trie {
    class TrieNode{
        private char c;
        private Map<Character, TrieNode> map;
        private boolean isLeaf;   

        TrieNode() {
            this.map = new HashMap<>();
        }
        TrieNode(char c) {
            this.c = c;
            this.map = new HashMap<>();
        }
    }
    private TrieNode root;
    /** Initialize your data structure here. */
    public Trie() {
        root = new TrieNode();
    }

    /** Inserts a word into the trie. */
    public void insert(String word) {
        TrieNode currNode = root;
        for(int i = 0; i < word.length(); i++) {
            char currChar = word.charAt(i);
            if(!currNode.map.containsKey(currChar)) {
                TrieNode newNode = new TrieNode(currChar);    
                currNode.map.put(currChar, newNode);
                currNode = newNode;
            }
            else {
                currNode = currNode.map.get(currChar);
            }
            if(i == word.length() - 1) {
                currNode.isLeaf = true;
            }
        }
    }

    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        TrieNode currNode = root;
        for(int i = 0; i < word.length(); i++) {
            if(!currNode.map.containsKey(word.charAt(i))) {
                return false;
            }
            currNode = currNode.map.get(word.charAt(i));
            if( i == word.length() - 1 && !currNode.isLeaf) {
                return false;
            }
        }
        return true;
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
        TrieNode currNode = root;
        for(int i = 0; i < prefix.length(); i++) {
            if(!currNode.map.containsKey(prefix.charAt(i))) {
                return false;
            }
            currNode = currNode.map.get(prefix.charAt(i));
        }
        return true;        
    }
}