파일에서 문자열 목록을 읽고 데이터 구조에 저장해야하는 응용 프로그램을 작성하고 있습니다 접두어로 그 문자열을 찾으십시오. 문자열 목록은 지정된 언어의 단어 목록입니다. 예를 들어 검색 함수가 매개 변수로 "stup"을 얻으면 [ "stupid", "stupidity", "stupor"...]를 반환해야합니다. 그것은 O (log (n) * m) 시간에 수행되어야하는데, 여기서 n은 데이터 구조의 크기이고 m은 결과의 수이며 가능한 한 빨리되어야합니다. 메모리 소비는 지금 큰 문제가 아닙니다. 나는 이것을 파이썬으로 작성하고 있으므로 파이썬 랩퍼를 사용하여 C로 구현 된 적합한 데이터 구조를 가리킬 수 있다면 좋을 것이다.빠른 접두사 검색을 사용하는 읽기 전용 문자열 목록 (약 100,000)에 대해 가장 효율적인 데이터 구조
답변
트라이가 필요합니다.
http://en.wikipedia.org/wiki/Trie
내가 스크래블과 머뭇 거리는 프로그램을 사용했습니다. 설명 된 유스 케이스에 완벽합니다 (빠른 접두사 조회).
다음은 Python으로 trie를 작성하기위한 몇 가지 샘플 코드입니다. 이것은 몇 달 전에 함께 휘젓는 Boggle 프로그램에서 나온 것입니다. 나머지는 독자에게 운동으로 남아 있습니다. 그러나 접두어 검사를 위해서는 기본적으로 루트 노드 (변수 words
)에서 시작하여 연속되는 자식 노드의 접두사의 문자를 따르고 그런 경로가 발견되면 True를 반환하고 그렇지 않으면 False를 반환하는 메서드가 필요합니다.
class Node(object):
def __init__(self, letter='', final=False):
self.letter = letter
self.final = final
self.children = {}
def __contains__(self, letter):
return letter in self.children
def get(self, letter):
return self.children[letter]
def add(self, letters, n=-1, index=0):
if n < 0: n = len(letters)
if index >= n: return
letter = letters[index]
if letter in self.children:
child = self.children[letter]
else:
child = Node(letter, index==n-1)
self.children[letter] = child
child.add(letters, n, index+1)
def load_dictionary(path):
result = Node()
for line in open(path, 'r'):
word = line.strip().lower()
result.add(word)
return result
words = load_dictionary('dictionary.txt')
trie (or prefix tree)는 골목에서 소리가납니다. O (m) 길이의 접두사 문자열에 대한 검색을 수행 할 수 있습니다.
문자열 배열. 그것을 통해
이진 검색은 첫 경기가 다음도 여기에 이후의 모든 일치하는 그것을 통해 하나
(내가 원래 연결 한 목록을 한 단계 검색하는 ...하지만 물론이 무작위가 없습니다 액세스 그래서 이것은 (나는을 downvoted 이유 아마 설명) 'BS'이었다 내 이진 검색 알고리즘은 아직 갈 수있는 가장 빠른 방법입니다하지만 tries의
맙소사, 그 남자에게 휴식을주십시오. – moo
많은 downvotes, 그리고 아무도 이유를 설명하고 신경? 사람들이 쌓이는 것처럼 느껴집니다. 이 대답은 원래 사용자가 요청한 모든 제약 조건을 충족하며 이해와 유지가 더 간단합니다. –
@reinier - 링크드리스트가 무작위 액세스에 좋지 않기 때문에 downvoted를 얻었습니다. 검색 시간은 요소 수에 선형입니다. 배열은 이미 정렬 되었으면 O (log n) 일 것이지만 trie는 O (m)입니다. 여기서 m은 접두어의 길이입니다. –
- 1. 대부분의 효율적인 데이터 구조 : 빠른 분류 삽입, 가장 가까운 값은
- 2. 구조 배열의 읽기 전용 복사본을 만드는 가장 빠른 방법은 무엇입니까?
- 3. 문자열의 읽기 전용 목록
- 4. 접두어 검색을 지원하는 정렬 된 텍스트를위한 공간 효율적인 메모리 구조
- 5. 검색 정보를위한 가장 빠른 데이터 구조 C++
- 6. 빠른 랜덤 액세스, 검색, 삽입 및 삭제를위한 효율적인 데이터 구조
- 7. ID를 얻기위한 효율적인 데이터 구조
- 8. DDD에서 읽기 전용 목록에 대해 여러 저장소를 사용하는 방법
- 9. 자동 속성이있는 읽기 전용 목록
- 10. 메이크업 목록 항목 읽기 전용
- 11. 정적 읽기 전용 문자열 배열
- 12. 데이터 구조 - 목록
- 13. ORACLE에서 가장 빠른 OLEDB 읽기
- 14. 읽기 전용 멤버 데이터 serialize
- 15. 내 사이트에서 가장 좋은 검색을 구현하는 가장 빠른 방법은 무엇입니까?
- 16. 정렬 된 목록을위한 효율적인 데이터 구조
- 17. 빠른 회선 질의를위한 데이터 구조?
- 18. 읽기 전용 데이터 집합 필드
- 19. 가장 일반적인 속성과 항목을 비교하기위한 효율적인 데이터 구조
- 20. 읽기 전용 목록 상자에서 항목 제거
- 21. 웹 사이트 데이터베이스 구조 - 가장 효율적이고 효율적인 구조
- 22. 목록 데이터 구조 C# 효율성
- 23. C#으로 필터링 할 가장 빠른 데이터 구조
- 24. Java에서 가장 빠른 데이터 구조 (4D 시각화 처리)
- 25. 효율적인 분류 MySQL의 구조
- 26. 목록/사전을 통한 접두사 검색. .NET StringDictionary?
- 27. 읽기 전용 ASP 드롭 다운 목록
- 28. 문자열 초기화 및 읽기 전용 섹션
- 29. "읽기 전용"SelectedItem을 사용하는 WPF ListView
- 30. 가장 빠른 직렬화 데이터 형식 양식 PHP 읽기
나는 반복적 인 방법으로 Node.add()를 작성하는 유혹 것 : 데프 추가 (자체, 문자) : 다음 = 자기 N = LEN ((글자, 인덱스 == n-1) next = next.children [글자 안의 글자] 글자 안의 글자 수 : 글자 안의 글자 : next.children [글자] 편지] – hughdbrown
하지만 올바른 들여 쓰기와 선으로 상상해보십시오. 휴식. – hughdbrown
적은 메모리를 사용하는 트리 인 "DAWG"도 참조하십시오. 그러나 (최소한 trie와 비교하여) 구축하는 것은 복잡합니다. – Fantius