위대한 질문입니다.
이진 검색의 문제점은 O (1)의 각 단계에서 요소의 절반을 건너 뛸 수 있다는 것에서 비롯됩니다. 이렇게하면 O (lg n) 개의 프로브 만 수행하므로 런타임은 O (lg n)가됩니다.이것은 예를 들어 배열에 대해 빠른 이진 검색을 수행 할 수 있지만 링크 된 목록에는 포함되지 않습니다. 링크 된 목록에서 요소의 중 간 지점을 찾는 데 선형 시간이 걸리므로 검색 시간이 지배적입니다.
파일에서 이진 검색을 할 때 비슷한 위치에 있습니다. 파일의 모든 행이 같은 길이가 아니기 때문에, 파일 번호 n이 주어진 경우 파일의 n 번째 행으로 쉽게 건너 뛸 수 없습니다. 결과적으로 파일에 대해 좋은, 빠른 이진 검색을 구현하는 것은 약간 까다 롭습니다. 어떻게 든 파일 내에서 효율적으로 이동할 수 있도록 각 행의 시작 및 중단 위치를 알아야합니다.
이렇게하는 방법에는 여러 가지가 있습니다. 먼저, 제안한 것처럼 파일의 모든 문자열을 배열로로드 할 수 있습니다. 이것은 선형 시간이 걸리지 만 메모리에 문자열 배열이 있으면 이후의 모든 바이너리 검색이 매우 빨라집니다. 캐치 (catch)는 파일 크기가 매우 큰 경우 많은 메모리를 차지할 수 있으며 엄청나게 커질 수 있다는 점입니다. 결과적으로, 또 다른 대안은 실제 문자열을 배열에 저장하는 것이 아니라 각 문자열이 나타나는 파일에 오프셋을 저장하는 것입니다. 이렇게하면 바이너리 검색을 신속하게 수행 할 수 있습니다. 비교를 수행 할 때 파일을 적절한 오프셋으로 찾을 수 있습니다. 큰 스팅은 위의 공간보다 훨씬 공간 효율적 일 수 있습니다. 그리고 모든 문자열이 대략 같은 길이라면, 각 라인의 시작 위치를 직접 계산할 수 있도록 모든 라인을 고정 된 크기로 채울 수 있습니다.
좀 더 복잡한 솔루션을 구현하는 데 시간을 많이 소비하려는 경우 파일 전처리를 고려하여 줄 당 하나의 문자열 대신 파일 상단에 고정 소수점 목록 파일 내의 각 캐릭터 라인의 오프셋 (offset)를 포함한 폭의 정수. 이것은 기본적으로 위의 작업을 수행하지만 결과를 파일에 저장하여 이후의 이진 검색을 훨씬 빠르게 만듭니다. 나는 이런 종류의 파일 구조에 대해 약간의 경험이 있으며, 꽤 빠를 수있다.
정말로 도전적인 사람이라면 B- 트리를 사용하여 파일에 문자열을 저장할 수 있습니다. 그러면 원하는 디스크 읽기 횟수를 최소화하여 각 문자열을 엄청나게 빨리 검색 할 수 있습니다 할 것.
희망이 도움이됩니다.
차가움. 고마워요 – meburbo
. 메모리로 읽어 들여'bsearch()'를 사용하십시오. – chrisaycock
선의 오프셋을 저장할 필요는 없습니다. 'O'(m log n)'시간에' '\ n' '에 동기화하는 바이트에 바이너리 검색을 간단하게 수행 할 수 있습니다. 여기서'n'은 줄의 수이고'm'은 줄의 최대 길이입니다. 이것은 메모리에 파일을로드 할 수없고'fseek' /'fseeko'를 사용해야 만하더라도 작동합니다. –