minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
原题链接🔗:Implementar Trie (árvore de prefixos)
dificuldade: Médio⭐️⭐️
Trie (pronunciado como "tentar") ou árvore de prefixos É uma estrutura de dados em árvore usada para armazenar e recuperar chaves com eficiência em um conjunto de dados de string. Essa estrutura de dados tem alguns casos de uso, como preenchimento automático e verificação ortográfica.
Implemente a classe Trie:
Trie()
Inicialize o objeto da árvore de prefixos.void insert(String word)
Inserir string na árvore de prefixosword
。boolean search(String word)
se stringword
Na árvore de prefixos, retorne true
(ou seja, foi inserido antes da recuperação); caso contrário, retorna false
。boolean startsWith(String prefix)
Se a string foi inserida antes word
Um dos prefixos é prefix
,retornar true
; Caso contrário, retornefalse
。Exemplo:
digitar
[“Trie”, “inserir”, “pesquisar”, “pesquisar”, “começa com”, “inserir”, “pesquisar”]
[[], [“maçã”], [“maçã”], [“aplicativo”], [“aplicativo”], [“aplicativo”], [“aplicativo”]]
saída
[nulo, nulo, verdadeiro, falso, verdadeiro, nulo, verdadeiro]
explicar
Trie trie = novo Trie();
trie.insert(“maçã”);
trie.search("apple"); // Retorna Verdadeiro
trie.search("app"); // Retorna Falso
trie.startsWith("app"); // Retorna Verdadeiro
trie.insert(“aplicativo”);
trie.search("app"); // Retorna Verdadeiro
dica:
Uma árvore de prefixos, também conhecida como árvore Trie (pronuncia-se "try"), é uma estrutura de dados usada para armazenar coleções de strings, que permite recuperação e inserção rápida de strings, bem como consultas para prefixos de strings. Cada nó da árvore de prefixos representa um prefixo de uma string, e os filhos de cada nó representam todas as extensões possíveis do prefixo que adicionam um caractere.
- Características das árvores de prefixo:
- eficiência de espaço: para coleções de strings com um grande número de prefixos comuns, as árvores de prefixos podem economizar espaço de armazenamento.
- Eficiência de tempo: A complexidade de tempo das operações de inserção e pesquisa é geralmente O(m), onde m é o comprimento da string.
- coleção dinâmica: a árvore de prefixos pode inserir e excluir strings dinamicamente, o que é adequado para cenários que exigem atualizações frequentes.
- Operações básicas de árvores de prefixo:
- inserir: Insira uma string na árvore, começando no nó raiz e descendo caractere por caractere. Se o nó filho correspondente ao caractere não existir, crie um novo nó.
- procurar: Pesquise se existe uma string na árvore, começando no nó raiz e descendo caractere por caractere. Se o nó filho de um caractere não existir, a pesquisa falhará.
- Pesquisa de prefixo: Verifica se existe alguma string prefixada por uma determinada string, semelhante à operação de busca, mas não precisa verificar o flag final do último nó.
- excluir: a exclusão de uma string de uma árvore requer a exclusão de nós recursivamente, garantindo ao mesmo tempo que os nós de prefixo comuns de outras strings não sejam excluídos.
- Cenários de aplicação da árvore de prefixos:
- autocompletar: em mecanismos de busca ou editores de texto, fornece rapidamente sugestões de preenchimento com base nos prefixos inseridos pelo usuário.
- Verificação ortográfica: verifica se a palavra digitada pelo usuário está escrita corretamente e fornece sugestões de ortografia corretas.
- Roteamento IP: Em uma rede, a correspondência de prefixo mais longo é usada para determinar o caminho de roteamento de um pacote.
- Análise de sequência genética: Em bioinformática, usado para combinar e recuperar rapidamente sequências genéticas.
Um Trie (árvore de prefixo) é uma estrutura de dados em árvore usada para recuperação rápida de chaves em um conjunto de dados de string. É um tipo especial de árvore em que cada nó representa um caractere e o caminho da raiz até um nó representa uma string. As árvores Trie são frequentemente usadas para implementar funções como preenchimento automático e verificação ortográfica.
A seguir estão as etapas básicas e ideias de resolução de problemas para implementar uma árvore Trie:
Definir nós Trie:
- Cada nó Trie geralmente contém um conjunto de caracteres ou um valor booleano para representar o final da palavra e ponteiros para nós filhos.
Inicializar teste:
- Crie um nó raiz que não contenha caracteres, mas que sirva como ponto de partida para todas as palavras.
operação de inserção:
- A partir do nó raiz, para cada caractere da string a ser inserido:
- Se o nó filho correspondente ao personagem não existir, crie um novo nó filho.
- Mova o nó atual para o nó filho correspondente.
Operação de pesquisa:
- Começando no nó raiz, para cada caractere da string que você deseja pesquisar:
- Se o nó filho correspondente ao caractere existir, continue a pesquisa.
- Se não existir, uma falha de pesquisa será retornada.
Pesquisa de prefixo:
- Semelhante à operação de pesquisa, mas só se preocupa se o prefixo da string existe.
Excluir operação(opcional):
- Implemente a capacidade de excluir palavras conforme necessário, o que geralmente envolve a exclusão de nós e requer o tratamento da contagem de referências do nó.
Função de preenchimento automático(opcional):
- Dado um prefixo, retorne todas as strings começando com esse prefixo.
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
class Trie {
private:
vector<Trie*> children;
bool isEnd;
Trie* searchPrefix(string prefix) {
Trie* node = this;
for (char ch : prefix) {
ch -= 'a';
if (node->children[ch] == nullptr) {
return nullptr;
}
node = node->children[ch];
}
return node;
}
public:
Trie() : children(26), isEnd(false) {}
void insert(string word) {
Trie* node = this;
for (char ch : word) {
ch -= 'a';
if (node->children[ch] == nullptr) {
node->children[ch] = new Trie();
}
node = node->children[ch];
}
node->isEnd = true;
}
bool search(string word) {
Trie* node = this->searchPrefix(word);
return node != nullptr && node->isEnd;
}
bool startsWith(string prefix) {
return this->searchPrefix(prefix) != nullptr;
}
};
int main() {
Trie trie;
trie.insert("apple");
std::cout << trie.search("apple") << std::endl; // 返回 1
std::cout << trie.search("app") << std::endl; // 返回 0
std::cout << trie.startsWith("app") << std::endl; // 返回 1
return 0;
}
1
0
1