Sistema de preenchimento automático da pesquisa de projeto

Projete um sistema de preenchimento automático de pesquisa para um mecanismo de pesquisa. Os usuários podem inserir uma frase (pelo menos uma palavra e terminar com um caractere especial  '#'). Para  cada caractere  digitado,  exceto '#' , é necessário retornar as  três principais  frases históricas importantes com o prefixo igual à parte da frase já digitada. Aqui estão as regras específicas:

  1. O grau quente de uma frase é definido como o número de vezes que um usuário digitou exatamente a mesma frase antes.
  2. As três principais frases quentes retornadas devem ser classificadas por grau quente (a primeira é a mais quente). Se várias frases tiverem o mesmo grau de calor, você precisará usar a ordem do código ASCII (a menor aparecerá primeiro).
  3. Se houver menos de três frases quentes, retorne o máximo que puder.
  4. Quando a entrada é um caractere especial, significa que a frase termina e, nesse caso, você precisa retornar uma lista vazia.

Seu trabalho é implementar as seguintes funções:

A função construtora:

AutocompleteSystem(String[] sentences, int[] times): Este é o construtor. A entrada são  dados históricosSentences é uma matriz de cadeias de caracteres que consiste em frases digitadas anteriormente. Times é o horário correspondente em que uma frase foi digitada. Seu sistema deve registrar esses dados históricos.

Agora, o usuário deseja inserir uma nova frase. A função a seguir fornecerá o próximo caractere digitado pelo usuário:

List<String> input(char c): A entrada  c é o próximo caractere digitado pelo usuário. O caractere será apenas letras minúsculas ( 'a' para  'z'), espaço em branco ( ' ') ou um caractere especial ( '#'). Além disso, a frase digitada anteriormente deve ser gravada no seu sistema. A saída será as  três principais  frases quentes históricas que têm o prefixo igual à parte da frase já digitada.

Exemplo:
Operação:  AutocompleteSystem (["eu te amo", "ilha", "homem de ferro", "eu amo código leet"], [5,3,2,2])
O sistema já rastreou as seguintes frases e suas correspondências vezes:
"i love you" :  5 tempos
"island" :  3 tempos
"ironman" :  2 tempos
"i love leetcode" :  2 tempos
agora, o usuário começa outra pesquisa:

Operation:  entrada ( 'i')
saída:  [ "eu te amo", "ilha", "eu amo leetcode"]
Explicação:
Existem quatro frases com prefixo  "i". Entre eles, "ironman" e "eu amo leetcode" têm o mesmo grau quente. Como  ' ' possui o código ASCII 32 e 'r' possui o código ASCII 114, "eu amo leetcode" deve estar na frente de "ironman". Também precisamos apenas emitir as três principais frases quentes, para que "ironman" seja ignorado.

Ideia: Essa pergunta é exatamente a mesma do Sistema de Sugestões de Pesquisa . A diferença sutil é que, após o término do tipo de entrada, a entrada de palavras também deve inserir as estatísticas de frequência da palavra. Em seguida, a frequência da sentença precisa ser armazenada no trienode. É nulo, então o futuro cur também é nulo,

class AutocompleteSystem {
    private class TrieNode {
        public HashMap<Character, TrieNode> children;
        public HashMap<String, Integer> counts;
        public boolean isword;
        public TrieNode() {
            this.children = new HashMap<Character, TrieNode>();
            this.counts = new HashMap<String, Integer>();
            this.isword = false;
        }
    }
    
    private class Trie {
        private TrieNode root;
        
        public Trie() {
            this.root = new TrieNode();
        }
        
        public void insert(String sentence, int time) {
            TrieNode cur = root;
            for(char c : sentence.toCharArray()) {
                TrieNode next = cur.children.get(c);
                if(next == null) {
                    next = new TrieNode();
                    cur.children.put(c, next);
                }
                cur = next;
                cur.counts.put(sentence, cur.counts.getOrDefault(sentence, 0) + time);
            }
            cur.isword = true;
        }
    }
    
    private class Node {
        private String sentence;
        private int fre;
        public Node(String sentence, int fre) {
            this.sentence = sentence;
            this.fre = fre;
        }
    }
    
    private class NodeComparator implements Comparator<Node> {
        @Override
        public int compare(Node a, Node b) {
            if(a.fre != b.fre) {
                return b.fre - a.fre;
            } else {
                return a.sentence.compareTo(b.sentence);
            }
        }
    }

    private Trie trie;
    private StringBuilder sb;
    private TrieNode cur;
    private String prefix;
    public AutocompleteSystem(String[] sentences, int[] times) {
        trie  = new Trie();
        for(int i = 0; i < sentences.length; i++) {
            trie.insert(sentences[i], times[i]);
        }
        prefix = "";
        sb = new StringBuilder();
        cur = trie.root;
    }
    
    public List<String> input(char c) {
        if(c == '#') {
            trie.insert(sb.toString(), 1);
            sb = new StringBuilder();
            cur = trie.root;
            return new ArrayList<String>();
        }
        sb.append(c);
        // 注意这里,如果下面没有了,那么以后也没有了,cur 赋值为null;
        if(cur == null || !cur.children.containsKey(c)) {
            cur = null;
            return new ArrayList<String>();
        } else {
            cur = cur.children.get(c);
            PriorityQueue<Node> pq = new PriorityQueue<Node>(new NodeComparator());
            for(String sentence: cur.counts.keySet()) {
                pq.add(new Node(sentence, cur.counts.get(sentence)));
            }
            List<String> list = new ArrayList<String>();
            int count = 0;
            while(!pq.isEmpty() && count < 3) {
                Node node = pq.poll();
                list.add(node.sentence);
                count++;
            }
            return list;
        }
    }
}

/**
 * Your AutocompleteSystem object will be instantiated and called as such:
 * AutocompleteSystem obj = new AutocompleteSystem(sentences, times);
 * List<String> param_1 = obj.input(c);
 */

 

Publicado 710 artigos originais · Gosto 13 · Visitas: mais de 190.000

Acho que você gosta

Origin blog.csdn.net/u013325815/article/details/105489360
Recomendado
Clasificación