AutoCorrectionUtils.java revision e784148ae6872942434eaa55ca32b4c6442cc8e8
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.inputmethod.latin.utils; 18 19import com.android.inputmethod.latin.BinaryDictionary; 20import com.android.inputmethod.latin.LatinImeLogger; 21import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; 22 23import android.util.Log; 24 25public final class AutoCorrectionUtils { 26 private static final boolean DBG = LatinImeLogger.sDBG; 27 private static final String TAG = AutoCorrectionUtils.class.getSimpleName(); 28 private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; 29 30 private AutoCorrectionUtils() { 31 // Purely static class: can't instantiate. 32 } 33 34 public static boolean suggestionExceedsAutoCorrectionThreshold( 35 final SuggestedWordInfo suggestion, final String consideredWord, 36 final float autoCorrectionThreshold) { 37 if (null != suggestion) { 38 // Shortlist a whitelisted word 39 if (suggestion.mKind == SuggestedWordInfo.KIND_WHITELIST) return true; 40 final int autoCorrectionSuggestionScore = suggestion.mScore; 41 // TODO: when the normalized score of the first suggestion is nearly equals to 42 // the normalized score of the second suggestion, behave less aggressive. 43 final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore( 44 consideredWord, suggestion.mWord, autoCorrectionSuggestionScore); 45 if (DBG) { 46 Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + "," 47 + autoCorrectionSuggestionScore + ", " + normalizedScore 48 + "(" + autoCorrectionThreshold + ")"); 49 } 50 if (normalizedScore >= autoCorrectionThreshold) { 51 if (DBG) { 52 Log.d(TAG, "Auto corrected by S-threshold."); 53 } 54 return !shouldBlockAutoCorrectionBySafetyNet(consideredWord, suggestion.mWord); 55 } 56 } 57 return false; 58 } 59 60 // TODO: Resolve the inconsistencies between the native auto correction algorithms and 61 // this safety net 62 public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord, 63 final String suggestion) { 64 // Safety net for auto correction. 65 // Actually if we hit this safety net, it's a bug. 66 // If user selected aggressive auto correction mode, there is no need to use the safety 67 // net. 68 // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, 69 // we should not use net because relatively edit distance can be big. 70 final int typedWordLength = typedWord.length(); 71 if (typedWordLength < MINIMUM_SAFETY_NET_CHAR_LENGTH) { 72 return false; 73 } 74 final int maxEditDistanceOfNativeDictionary = (typedWordLength / 2) + 1; 75 final int distance = BinaryDictionaryUtils.editDistance(typedWord, suggestion); 76 if (DBG) { 77 Log.d(TAG, "Autocorrected edit distance = " + distance 78 + ", " + maxEditDistanceOfNativeDictionary); 79 } 80 if (distance > maxEditDistanceOfNativeDictionary) { 81 if (DBG) { 82 Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion); 83 Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " 84 + "Turning off auto-correction."); 85 } 86 return true; 87 } else { 88 return false; 89 } 90 } 91} 92