2012-03-27 7 views
5

큰 세트의 URL이 있는데 자동 완성을 구현하고 싶습니다. 이 세트의 크기와 선형이기 때문에 나는 순진 접근 방식의 복잡성을 좋아하지 않는다 :Java에서 간단한 접두사 색인을 만드는 방법은 무엇입니까?

지금은 해시 세트에서, 함수가 O "의 작품"(을)를 포함 "알고
for(String url: urls) if(url.startsWith(input) {doSomething();} 

(1) "containsPrefix()"는 없습니다. Lucene과 같은 큰 라이브러리를 사용하거나 직접 코딩하지 않고도 간단한 방법이 있습니까? 문제가 없지만 간단한 문제가 너무 복잡해서 기존의 간단한 해결책이 있는지 알고 싶습니다. :-)

컴퓨터 과학 수업에서 문자열 조각으로 구성된 트리를 기억하지만 나는 그것이 어떻게 부르는지 잊는다. 그것은 다음과 같이 작동했습니다 :

[car, care, carrot,carrotville]-> 

car 
| 
-/ 
-e 
-rrot 
    | 
    ----ville 

P .: 나는 문자열이 접두사 인 모든 문자열을 반환하는 메소드를 어떻게 호출합니까? a가 b의 접두사 인 것처럼, b는 무엇입니까? 당신이 Trie, 그 목적을 위해 정밀하게 설계된 데이터 구조를 사용, 효율적으로 문자열의 접두사를 찾을 필요가

+0

무엇을 하시겠습니까? 자동으로 모든 문자열의 시작 부분에 텍스트를 추가합니까? –

+0

내 문자열이 접두사 인 문자열을 알고 싶습니다. 그래서 자동 완성 제안으로 줄 수 있습니다. –

답변

2

:

트라이, 또는 접두사 트리에 사용되는 명령 트리 데이터 구조입니다 키가 일반적으로 문자열 인 연관 배열을 저장합니다. 이진 검색 트리와 달리 트리의 아무 노드도 해당 노드와 연관된 키를 저장하지 않습니다. 대신 트리의 해당 위치는 키가 연결된 키를 정의합니다. 노드의 모든 후손은 해당 노드와 관련된 문자열의 공통 접두어가, 루트는 빈 문자열로 sampleimplementations

두 링크가 연결되어 있습니다.

+1

완벽! 나는 https://forums.oracle.com/forums/thread.jspa?messageID=8787521의 파일을 사용했고, 첫 번째 시도에서 작동했습니다! –

1

오래 전에 내가 여기에 간단한 트리는 구현을 넣어 :

http://code.google.com/p/triebag/source/browse/trunk/src/triebag/tries/SimpleTrie.java

그러나이 소형 트리는 아니다, 그래서 컴팩트 한 조금 까다 롭습니다 만들기, 캐릭터 당 하나 개의 노드를 작성합니다.

+0

대단하군요! 캐릭터 당 하나의 노드 일지라도 상관 없지만 누군가가 배수가있는 경우를 대비하여 질문을 공개 할 것입니다. –

+0

Np, 컴팩트 버전은 약 % 50 개 이하의 노드를 사용합니다 (사전의 터키어 단어에 대해서는 적어도). 이 코드는 테스트 코드이므로 실제로 작동하는 것을 볼 수 있습니다. 아무런 버그가 없기를 바랍니다 :) http : // /code.google.com/p/triebag/source/browse/trunk/test/triebag/tries/SimpleTrieTest.java – mdakin

+0

SimpleTrie을 사용해 보았지만 나에게 적합하지 않은 것 같습니다. 처음에는 생성자가 public이 아니었고, 변경 한 후에는 다음과 같은 결과는 아무 것도 반환하지 않았습니다 :'SimpleTrie trie = new SimpleTrie <>(); \t \t trie.add ("x", "x"); \t \t trie.add ("xy", "xy"); \t \t Iterator it = trie.getItemsWithPrefix ("x"); \t \t while (it.hasNext()) System.out.println (it.next());' –

0
효율적으로 접두사 처리 할 수 ​​

정규 표현식 구현 있으며, java.util.regex.Pattern :

StringBuilder buffer = new StringBuilder(); 
for (String prefix : prefixes) { 
    if (buffer.length() > 0) 
     buffer.append("|"); 
    buffer.append(prefix); 
} 
Pattern prefixPattern = Pattern.compile("^(" + buffer + ")"); 

당신은 모든 접두사를 테스트 할 수 있습니다

boolean containsPrefix = prefixPattern.matcher(stringToTest).find(); 

참고 : 간단히 말하면 접두사 문자열은 이스케이프되지 않습니다. 정규 표현식 문자 [,], \, *,?, $, ^, (,), {,} 및 | \가 앞에 붙어야한다.

관련 문제