@Override public int compareTo(final CandidateData cd) { // Assume no overflow. return cd.getDistance() > this.distance ? -1 : cd.getDistance() == this.distance ? 0 : 1; }
/** * Find suggestions by using K. Oflazer's algorithm. See Jan Daciuk's s_fsa package, spell.cc for * further explanation. * * @param w The original misspelled word. * @return A list of suggested replacements. */ public List<String> findReplacements(final String w) { String word = w; if (!dictionaryMetadata.getInputConversionPairs().isEmpty()) { word = DictionaryLookup.applyReplacements(w, dictionaryMetadata.getInputConversionPairs()); } candidates.clear(); if (word.length() > 0 && word.length() < MAX_WORD_LENGTH && !isInDictionary(word)) { List<String> wordsToCheck = new ArrayList<String>(); if (replacementsTheRest != null && word.length() > MIN_WORD_LENGTH) { for (final String wordChecked : getAllReplacements(word, 0, 0)) { boolean found = false; if (isInDictionary(wordChecked)) { candidates.add(new CandidateData(wordChecked, 0)); found = true; } else if (dictionaryMetadata.isConvertingCase()) { String lowerWord = wordChecked.toLowerCase(dictionaryMetadata.getLocale()); String upperWord = wordChecked.toUpperCase(dictionaryMetadata.getLocale()); if (isInDictionary(lowerWord)) { // add the word as it is in the dictionary, not mixed-case versions of it candidates.add(new CandidateData(lowerWord, 0)); found = true; } if (isInDictionary(upperWord)) { candidates.add(new CandidateData(upperWord, 0)); found = true; } if (lowerWord.length() > 1) { String firstupperWord = Character.toUpperCase(lowerWord.charAt(0)) + lowerWord.substring(1); if (isInDictionary(firstupperWord)) { candidates.add(new CandidateData(firstupperWord, 0)); found = true; } } } if (!found) { wordsToCheck.add(wordChecked); } } } else { wordsToCheck.add(word); } // If at least one candidate was found with the replacement pairs (which are usual errors), // probably there is no need for more candidates if (candidates.isEmpty()) { int i = 1; for (final String wordChecked : wordsToCheck) { i++; if (i > UPPER_SEARCH_LIMIT) { // for performance reasons, do not search too deeply break; } wordProcessed = wordChecked.toCharArray(); wordLen = wordProcessed.length; if (wordLen < MIN_WORD_LENGTH && i > 2) { // three-letter replacements make little sense anyway break; } candidate = new char[MAX_WORD_LENGTH]; candLen = candidate.length; effectEditDistance = wordLen <= editDistance ? wordLen - 1 : editDistance; charBuffer = BufferUtils.clearAndEnsureCapacity(charBuffer, MAX_WORD_LENGTH); byteBuffer = BufferUtils.clearAndEnsureCapacity(byteBuffer, MAX_WORD_LENGTH); final byte[] prevBytes = new byte[0]; findRepl(0, fsa.getRootNode(), prevBytes, 0, 0); } } } Collections.sort(candidates); // Use a linked set to avoid duplicates and preserve the ordering of candidates. final Set<String> candStringSet = new LinkedHashSet<String>(); for (final CandidateData cd : candidates) { candStringSet.add( DictionaryLookup.applyReplacements( cd.getWord(), dictionaryMetadata.getOutputConversionPairs()) .toString()); } final List<String> candStringList = new ArrayList<String>(candStringSet.size()); candStringList.addAll(candStringSet); return candStringList; }