내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
原题链接🔗:Trie 구현(접두사 트리)
어려움: 중간⭐️⭐️
Trie("시도"처럼 발음) 또는 접두사 트리 문자열 데이터세트에서 키를 효율적으로 저장하고 검색하는 데 사용되는 트리 데이터 구조입니다. 이 데이터 구조에는 자동 완성 및 맞춤법 검사와 같은 꽤 많은 사용 사례가 있습니다.
Trie 클래스를 구현하십시오.
Trie()
접두사 트리 개체를 초기화합니다.void insert(String word)
접두사 트리에 문자열 삽입word
。boolean search(String word)
문자열이면word
접두사 트리에서 반환 true
(즉, 검색 전에 삽입되었습니다), 그렇지 않으면 반환됩니다. false
。boolean startsWith(String prefix)
문자열이 이전에 삽입된 경우 word
접두사 중 하나는 다음과 같습니다. prefix
,반품 true
; 그렇지 않으면 반환false
。예:
입력하다
[“Trie”, “삽입”, “검색”, “검색”, “startsWith”, “삽입”, “검색”]
[[], [“애플”], [“애플”], [“앱”], [“앱”], [“앱”], [“앱”]]
산출
[null,null,true,false,true,null,true]
설명하다
트라이 트라이 = 새로운 트라이();
trie.insert("사과");
trie.search("apple"); // True를 반환합니다.
trie.search("app"); // 거짓 반환
trie.startsWith("app"); // True를 반환합니다.
trie.insert("앱");
trie.search("app"); // True를 반환합니다.
힌트:
Trie 트리("try"로 발음)라고도 알려진 접두사 트리는 문자열 모음을 저장하는 데 사용되는 데이터 구조로, 문자열 접두사에 대한 쿼리뿐만 아니라 문자열의 빠른 검색 및 삽입을 허용합니다. 접두사 트리의 각 노드는 문자열의 접두사를 나타내고, 각 노드의 자식은 한 문자를 추가하는 접두사의 가능한 모든 확장을 나타냅니다.
- 접두사 트리의 특성:
- 공간 효율성: 공통 접두사가 많은 문자열 모음의 경우 접두사 트리를 사용하면 저장 공간을 절약할 수 있습니다.
- 시간 효율성: 삽입 및 검색 작업의 시간 복잡도는 일반적으로 O(m)입니다. 여기서 m은 문자열의 길이입니다.
- 동적 컬렉션: 접두사 트리는 문자열을 동적으로 삽입하고 삭제할 수 있으므로 자주 업데이트해야 하는 시나리오에 적합합니다.
- 접두사 트리의 기본 작업:
- 끼워 넣다: 루트 노드부터 한 문자씩 아래로 내려가는 문자열을 트리에 삽입합니다. 해당 문자에 해당하는 하위 노드가 없으면 새 노드를 만듭니다.
- 찾다: 루트 노드부터 한 문자씩 아래로 트리에 문자열이 있는지 검색합니다. 해당 문자의 하위 노드가 없으면 검색이 실패합니다.
- 접두사 검색: 검색 작업과 유사하게 특정 문자열이 앞에 붙은 문자열이 있는지 확인하지만 마지막 노드의 종료 플래그를 확인할 필요는 없습니다.
- 삭제: 트리에서 문자열을 삭제하려면 다른 문자열의 공통 접두사 노드가 삭제되지 않도록 하면서 노드를 재귀적으로 삭제해야 합니다.
- 접두사 트리의 응용 시나리오:
- 자동완성: 검색 엔진이나 텍스트 편집기에서 사용자가 입력한 접두사를 기반으로 신속하게 완성 제안을 제공합니다.
- 맞춤법 검사: 사용자가 입력한 단어의 철자가 올바른지 확인하고 올바른 철자를 제안합니다.
- IP 라우팅: 네트워크에서는 가장 긴 접두사 일치를 사용하여 패킷의 라우팅 경로를 결정합니다.
- 유전자 서열 분석: 생물정보학에서 유전자 서열을 신속하게 일치시키고 검색하는 데 사용됩니다.
Trie(접두사 트리)는 문자열 데이터세트에서 키를 빠르게 검색하는 데 사용되는 트리 데이터 구조입니다. 각 노드가 문자를 나타내고 루트에서 노드까지의 경로가 문자열을 나타내는 특별한 종류의 트리입니다. 트라이 트리는 자동 완성, 맞춤법 검사 등의 기능을 구현하는 데 자주 사용됩니다.
다음은 Trie 트리 구현을 위한 기본 단계와 문제 해결 아이디어입니다.
Trie 노드 정의:
- 각 Trie 노드에는 일반적으로 단어의 끝을 나타내는 문자 집합이나 부울 값과 하위 노드에 대한 포인터가 포함되어 있습니다.
트라이 초기화:
- 문자는 포함하지 않지만 모든 단어의 시작점 역할을 하는 루트 노드를 만듭니다.
삽입 작업:
- 루트 노드부터 시작하여 삽입할 문자열의 각 문자에 대해 다음을 수행합니다.
- 해당 캐릭터에 해당하는 자식 노드가 존재하지 않는 경우, 새로운 자식 노드를 생성합니다.
- 현재 노드를 해당 하위 노드로 이동합니다.
검색작업:
- 루트 노드부터 시작하여 검색하려는 문자열의 각 문자에 대해 다음을 수행합니다.
- 해당 캐릭터에 해당하는 자식 노드가 존재하면 검색을 계속합니다.
- 존재하지 않으면 검색 실패가 반환됩니다.
접두사 검색:
- 검색 작업과 유사하지만 문자열의 접두사가 존재하는지 여부에만 관심이 있습니다.
삭제 작업(선택 과목):
- 필요에 따라 단어를 삭제하는 기능을 구현합니다. 여기에는 일반적으로 노드 삭제가 포함되며 노드의 참조 카운트 처리가 필요합니다.
자동완성 기능(선택 과목):
- 접두사가 주어지면 해당 접두사로 시작하는 모든 문자열을 반환합니다.
#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