2010-07-14 3 views
13

사전 단어의 일반적인 트라이가 작성되었다고 가정하면 순회 중 대체, 삭제, 바꾸기 및 삽입 등 철자 오류의 4 가지 경우를 확인하는 가장 좋은 방법은 무엇입니까?맞춤법 추천을 확인하기 위해 Trie를 트래버스하는 좋은 알고리즘은 무엇입니까?

한 가지 방법은 주어진 단어의 n 편집 거리 내의 모든 단어를 찾아내어 Trie에서 검사하는 것입니다. 이것은 나쁜 선택은 아니지만 여기에 더 나은 직관은 탐색 중에 단어를 수정 한 후 가장 좋은 하위 시험을 결정하는 동적 프로그래밍 (또는 재귀 적 등가) 방법을 사용하는 것 같습니다.

어떤 아이디어라도 환영합니다!

추신 : 답변에있는 링크가 아닌 실제 입력을 주시면 감사하겠습니다.

+8

"Trie"가 보이고 "Tree"의 철자가 잘못되었다고 생각하면 문맥에 따라 엄청 아이러니하게 느껴질 것입니다. http://en.wikipedia.org/wiki/Trie – Manfre

답변

9

는 사실이 다른 일 할 수있는 몇 가지 코드 작성 :

https://bitbucket.org/teoryn/spell-checker/src/tip/spell_checker.py

그것은 피터 노빅 (http://norvig.com/spell-correct.html)에 의해 코드를 기반으로가 아니라 주어진 편집 내에서 단어를 찾기위한 트라이에 사전을 저장 거리가 더 빠릅니다.

알고리즘은 입력 단어의 문자를 소비함으로써 각 단계에서 가능한 편집 내용을 재귀 적으로 적용합니다. 재귀 호출의 매개 변수는 얼마나 많은 편집을 할 수 있는지를 나타냅니다. trie는 주어진 접두사에서 실제로 도달 할 수있는 문자를 확인하여 검색 공간을 좁히는 데 도움이됩니다. 예를 들어 문자를 삽입 할 때 각 문자를 알파벳으로 추가하는 대신 현재 노드에서 도달 할 수있는 문자 만 추가합니다. 편집하지 않는 것은 입력 단어의 현재 문자를 따라 트리의 현재 노드에서 분기를 가져 오는 것과 같습니다. 그 지점이 없다면 실제 단어가없는 큰 공간을 뒤돌아 검색하지 않아도됩니다.

+2

+1 코드. 코드에 더 까다로운 케이스가 없다는 것에 놀랐습니다. –

+0

링크가 죽었습니다 : \ –

+0

@ColonelPanic 죄송합니다. 링크를 수정했습니다. –

1

두 시퀀스 간의 거리를 찾는 동적 프로그래밍 솔루션을 제공하는 Levenshtein distance을 계산합니다.

+0

답변 해 주셔서 감사합니다. Levenshtein에 대해 알고 있습니다. 제가 다루고있는 문제는 어떤 단어를 비교할 것인지 모르겠다는 것입니다. 대신, 내가하고 싶은 일은 주어진 편집 거리 내에서 단어 목록을 생성하는 것입니다. – viksit

2

나는 나무에서 간단한 너비 우선 검색으로 이것을 할 수 있다고 생각합니다 : 찾고있는 오류 수의 임계 값을 선택하고, 한 번에 하나씩 일치시킬 단어의 문자를 실행하고, 접두사 일치까지 도달 (접두사, subtrie) 쌍의 세트를 생성하고, 당신이 당신의 오류 임계 값 아래에있는 동안, 다음 하위 목표의 당신의 세트에 추가

  1. 이 문자 장소 없음 오류 : subgoal 추가 단어의 다음 문자에서 트라이의 숫자
  2. 여기에 삽입, 삭제 또는 대체 된 문자가 있습니다. 적절한 위치에서 트라이를 찾고 오류 수를 증가시킵니다.
  3. 추가 목표는 없지만 전환은 이전 삭제 또는 삽입과 일치하는 삽입 또는 삭제입니다.이 테스트가 유지되면 오류 수를 증가시키지 마십시오.

이것은 꽤 순진한 것처럼 보입니다. 동적 프로그래밍을 생각하게 만드는 문제가 있습니까?

2

단어의 연속 된 각 문자를 트리의 한 레벨을 나타내는 것으로 가정하면 각 문자를 확인하는 5 가지 경우 (일치, 삭제, 삽입, 대체 및 조옮김)가 있습니다. 전치가 두 개의 인접한 문자라고 가정합니다.

확인할 트리 노드와 문자를 허용하는 함수 (CheckNode)가 필요합니다. 일치를 나타내는 (자식/그랜드 자식) 노드 집합을 반환해야합니다.

단어를 허용하는 함수 (CheckWord)가 필요합니다. 노드 집합과 차례로 각 문자를 검사합니다. 일치하는 단어를 나타내는 (리프) 노드 집합을 반환합니다.

트리의 각 레벨 (자식, 그랜드 자식 등)은 단어의 문자 위치와 일치한다는 개념입니다. 최상위 트리 노드 인 레벨 0을 호출하면 레벨 1, 레벨 2 등이됩니다.

오류가없는 단어의 경우 문자 위치와 레벨이 일대일로 일치합니다. 나무.

삭제의 경우 트리에서 수준을 건너 뛸 필요가 있습니다.

삽입의 경우 단어의 문자는 건너 뜁니다.

대체 할 경우 레벨과 문자를 건너 뛸 필요가 있습니다.

전조의 경우 단어의 문자를 일시적으로 바꿔야합니다.

+0

대체 문자를 인접 문자로 제한하는 것을 제외하고는 제 대답과 다른 점이 있습니까? –

+0

@Charles Stewart 아직 폭 넓은 첫 번째 검색에 동의합니다. 하지만 Viksit은 맞춤법 추천 (리프 노드)만을 원하므로 오류 수에 의존하지 않습니다. 또한 문제를 해결할 수있는 프로그램의 잠재적 구조에 대한 힌트를 제공합니다. –

관련 문제