diff options
16 files changed, 233 insertions, 103 deletions
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml index 9527fd62a..826565168 100644 --- a/java/res/values-sw600dp/config.xml +++ b/java/res/values-sw600dp/config.xml @@ -19,8 +19,6 @@ --> <resources> - <!-- Device form factor. This value must be aligned with {@link KeyboardId.FORM_FACTOR_TABLET7} --> - <integer name="config_device_form_factor">1</integer> <bool name="config_enable_show_voice_key_option">false</bool> <bool name="config_enable_show_option_of_key_preview_popup">false</bool> <bool name="config_enable_bigram_suggestions_option">false</bool> diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml index 3c2c19855..97f11cb04 100644 --- a/java/res/values-sw768dp/config.xml +++ b/java/res/values-sw768dp/config.xml @@ -19,8 +19,6 @@ --> <resources> - <!-- Device form factor. This value must be aligned with {@link KeyboardId.FORM_FACTOR_TABLET10} --> - <integer name="config_device_form_factor">2</integer> <bool name="config_enable_show_voice_key_option">false</bool> <bool name="config_enable_show_option_of_key_preview_popup">false</bool> <bool name="config_enable_bigram_suggestions_option">false</bool> diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 33e6a868c..23b579400 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -19,8 +19,6 @@ --> <resources> - <!-- Device form factor. This value must be aligned with {@link KeyboardId.FORM_FACTOR_PHONE} --> - <integer name="config_device_form_factor">0</integer> <bool name="config_use_fullscreen_mode">false</bool> <bool name="config_enable_show_voice_key_option">true</bool> <bool name="config_enable_show_option_of_key_preview_popup">true</bool> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java index c76acd126..60d09d6fd 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java @@ -94,6 +94,8 @@ public interface KeyboardActionListener { public boolean onCustomRequest(int requestCode); public static class Adapter implements KeyboardActionListener { + public static final Adapter EMPTY_LISTENER = new Adapter(); + @Override public void onPressKey(int primaryCode) {} @Override diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index ee8ee9a4f..aa27067bc 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -56,13 +56,8 @@ public final class KeyboardId { public static final int ELEMENT_PHONE_SYMBOLS = 8; public static final int ELEMENT_NUMBER = 9; - public static final int FORM_FACTOR_PHONE = 0; - public static final int FORM_FACTOR_TABLET7 = 1; - public static final int FORM_FACTOR_TABLET10 = 2; - public final InputMethodSubtype mSubtype; public final Locale mLocale; - public final int mDeviceFormFactor; // TODO: Remove this member. It is used only for logging purpose. public final int mOrientation; public final int mWidth; @@ -82,7 +77,6 @@ public final class KeyboardId { public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) { mSubtype = params.mSubtype; mLocale = SubtypeLocale.getSubtypeLocale(mSubtype); - mDeviceFormFactor = params.mDeviceFormFactor; mOrientation = params.mOrientation; mWidth = params.mKeyboardWidth; mHeight = params.mKeyboardHeight; @@ -107,7 +101,6 @@ public final class KeyboardId { private static int computeHashCode(final KeyboardId id) { return Arrays.hashCode(new Object[] { - id.mDeviceFormFactor, id.mOrientation, id.mElementId, id.mMode, @@ -130,8 +123,7 @@ public final class KeyboardId { private boolean equals(final KeyboardId other) { if (other == this) return true; - return other.mDeviceFormFactor == mDeviceFormFactor - && other.mOrientation == mOrientation + return other.mOrientation == mOrientation && other.mElementId == mElementId && other.mMode == mMode && other.mWidth == mWidth @@ -195,11 +187,11 @@ public final class KeyboardId { public String toString() { final String orientation = (mOrientation == Configuration.ORIENTATION_PORTRAIT) ? "port" : "land"; - return String.format("[%s %s:%s %s-%s:%dx%d %s %s %s%s%s%s%s%s%s%s%s]", + return String.format("[%s %s:%s %s:%dx%d %s %s %s%s%s%s%s%s%s%s%s]", elementIdToName(mElementId), mLocale, mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), - deviceFormFactor(mDeviceFormFactor), orientation, mWidth, mHeight, + orientation, mWidth, mHeight, modeName(mMode), imeAction(), (navigateNext() ? "navigateNext" : ""), @@ -238,15 +230,6 @@ public final class KeyboardId { } } - public static String deviceFormFactor(final int deviceFormFactor) { - switch (deviceFormFactor) { - case FORM_FACTOR_PHONE: return "phone"; - case FORM_FACTOR_TABLET7: return "tablet7"; - case FORM_FACTOR_TABLET10: return "tablet10"; - default: return null; - } - } - public static String modeName(final int mode) { switch (mode) { case MODE_TEXT: return "text"; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index 5e68c7067..bc9e8cdd4 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -106,7 +106,6 @@ public final class KeyboardLayoutSet { boolean mNoSettingsKey; boolean mLanguageSwitchKeyEnabled; InputMethodSubtype mSubtype; - int mDeviceFormFactor; int mOrientation; int mKeyboardWidth; int mKeyboardHeight; @@ -217,10 +216,8 @@ public final class KeyboardLayoutSet { mPackageName, NO_SETTINGS_KEY, mEditorInfo); } - public Builder setScreenGeometry(final int deviceFormFactor, final int widthPixels, - final int heightPixels) { + public Builder setScreenGeometry(final int widthPixels, final int heightPixels) { final Params params = mParams; - params.mDeviceFormFactor = deviceFormFactor; params.mOrientation = (heightPixels > widthPixels) ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; setDefaultKeyboardSize(widthPixels, heightPixels); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 4e41b77ce..39afe9072 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -142,8 +142,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mThemeContext, editorInfo); final Resources res = mThemeContext.getResources(); final DisplayMetrics dm = res.getDisplayMetrics(); - builder.setScreenGeometry(res.getInteger(R.integer.config_device_form_factor), - dm.widthPixels, dm.heightPixels); + builder.setScreenGeometry(dm.widthPixels, dm.heightPixels); builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype()); builder.setOptions( settingsValues.isVoiceKeyEnabled(editorInfo), diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index c1b148dbf..0556fddd3 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -176,7 +176,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private DrawingProxy mDrawingProxy; private TimerProxy mTimerProxy; private KeyDetector mKeyDetector; - private KeyboardActionListener mListener = EMPTY_LISTENER; + private KeyboardActionListener mListener = KeyboardActionListener.Adapter.EMPTY_LISTENER; private Keyboard mKeyboard; private int mPhantonSuddenMoveThreshold; @@ -333,10 +333,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // true if a sliding key input is allowed. private boolean mIsAllowedSlidingKeyInput; - // Empty {@link KeyboardActionListener} - private static final KeyboardActionListener EMPTY_LISTENER = - new KeyboardActionListener.Adapter(); - private final GestureStrokeWithPreviewPoints mGestureStrokeWithPreviewPoints; public static void init(final boolean needsPhantomSuddenMoveEventHack) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java index 53da47c52..93ff26466 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java @@ -83,9 +83,8 @@ public class GestureStroke { public final int mRecognitionMinimumTime; // msec public final float mRecognitionSpeedThreshold; // keyWidth/sec - // Default GestureStroke parameters for test. - public static final GestureStrokeParams FOR_TEST = new GestureStrokeParams(); - public static final GestureStrokeParams DEFAULT = FOR_TEST; + // Default GestureStroke parameters. + public static final GestureStrokeParams DEFAULT = new GestureStrokeParams(); private GestureStrokeParams() { // These parameter values are default and intended for testing. diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java index 477b36e10..235bcd7a5 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java @@ -65,15 +65,15 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { @Override public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { super.setKeyboardGeometry(keyWidth, keyboardHeight); - final float samplingRatioToKeyWidth = MIN_PREVIEW_SAMPLING_RATIO_TO_KEY_WIDTH; - mMinPreviewSamplingDistance = keyWidth * samplingRatioToKeyWidth; + mMinPreviewSamplingDistance = keyWidth * MIN_PREVIEW_SAMPLING_RATIO_TO_KEY_WIDTH; } - private boolean needsSampling(final int x, final int y, final boolean isMajorEvent) { + private boolean needsSampling(final int x, final int y) { mDistanceFromLastSample += Math.hypot(x - mLastX, y - mLastY); mLastX = x; mLastY = y; - if (mDistanceFromLastSample >= mMinPreviewSamplingDistance) { + final boolean isDownEvent = (mPreviewEventTimes.getLength() == 0); + if (mDistanceFromLastSample >= mMinPreviewSamplingDistance || isDownEvent) { mDistanceFromLastSample = 0.0d; return true; } @@ -83,7 +83,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { @Override public boolean addPointOnKeyboard(final int x, final int y, final int time, final boolean isMajorEvent) { - if (needsSampling(x, y, isMajorEvent)) { + if (needsSampling(x, y)) { mPreviewEventTimes.add(time); mPreviewXCoordinates.add(x); mPreviewYCoordinates.add(y); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index c03b77d98..61850e42e 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -283,20 +283,6 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { //suggestionsLimit); final SuggestionsGatherer suggestionsGatherer = mService.newSuggestionsGatherer( text, suggestionsLimit); - final WordComposer composer = new WordComposer(); - final int length = text.length(); - for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) { - final int codePoint = text.codePointAt(i); - // The getXYForCodePointAndScript method returns (Y << 16) + X - final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript( - codePoint, mScript); - if (SpellCheckerProximityInfo.NOT_A_COORDINATE_PAIR == xy) { - composer.add(codePoint, - Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); - } else { - composer.add(codePoint, xy & 0xFFFF, xy >> 16); - } - } final int capitalizeType = StringUtils.getCapitalizationType(text); boolean isInDict = true; @@ -306,6 +292,20 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { if (!DictionaryPool.isAValidDictionary(dictInfo)) { return AndroidSpellCheckerService.getNotInDictEmptySuggestions(); } + final WordComposer composer = new WordComposer(); + final int length = text.length(); + for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) { + final int codePoint = text.codePointAt(i); + // The getXYForCodePointAndScript method returns (Y << 16) + X + final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript( + codePoint, mScript); + if (SpellCheckerProximityInfo.NOT_A_COORDINATE_PAIR == xy) { + composer.add(codePoint, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); + } else { + composer.add(codePoint, xy & 0xFFFF, xy >> 16); + } + } // TODO: make a spell checker option to block offensive words or not final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getSuggestions(composer, prevWord, diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp index 0c65939e0..61bf3f619 100644 --- a/native/jni/src/correction.cpp +++ b/native/jni/src/correction.cpp @@ -23,6 +23,8 @@ #include "defines.h" #include "proximity_info_state.h" #include "suggest_utils.h" +#include "suggest/policyimpl/utils/edit_distance.h" +#include "suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h" namespace latinime { @@ -906,50 +908,11 @@ inline static bool isUpperCase(unsigned short c) { return totalFreq; } -/* Damerau-Levenshtein distance */ -inline static int editDistanceInternal(int *editDistanceTable, const int *before, - const int beforeLength, const int *after, const int afterLength) { - // dp[li][lo] dp[a][b] = dp[ a * lo + b] - int *dp = editDistanceTable; - const int li = beforeLength + 1; - const int lo = afterLength + 1; - for (int i = 0; i < li; ++i) { - dp[lo * i] = i; - } - for (int i = 0; i < lo; ++i) { - dp[i] = i; - } - - for (int i = 0; i < li - 1; ++i) { - for (int j = 0; j < lo - 1; ++j) { - const int ci = toBaseLowerCase(before[i]); - const int co = toBaseLowerCase(after[j]); - const int cost = (ci == co) ? 0 : 1; - dp[(i + 1) * lo + (j + 1)] = min(dp[i * lo + (j + 1)] + 1, - min(dp[(i + 1) * lo + j] + 1, dp[i * lo + j] + cost)); - if (i > 0 && j > 0 && ci == toBaseLowerCase(after[j - 1]) - && co == toBaseLowerCase(before[i - 1])) { - dp[(i + 1) * lo + (j + 1)] = min( - dp[(i + 1) * lo + (j + 1)], dp[(i - 1) * lo + (j - 1)] + cost); - } - } - } - - if (DEBUG_EDIT_DISTANCE) { - AKLOGI("IN = %d, OUT = %d", beforeLength, afterLength); - for (int i = 0; i < li; ++i) { - for (int j = 0; j < lo; ++j) { - AKLOGI("EDIT[%d][%d], %d", i, j, dp[i * lo + j]); - } - } - } - return dp[li * lo - 1]; -} - /* static */ int Correction::RankingAlgorithm::editDistance(const int *before, const int beforeLength, const int *after, const int afterLength) { - int table[(beforeLength + 1) * (afterLength + 1)]; - return editDistanceInternal(table, before, beforeLength, after, afterLength); + const DamerauLevenshteinEditDistancePolicy daemaruLevenshtein( + before, beforeLength, after, afterLength); + return static_cast<int>(EditDistance::getEditDistance(&daemaruLevenshtein)); } diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp index 3221dee9c..a18794850 100644 --- a/native/jni/src/suggest/core/suggest.cpp +++ b/native/jni/src/suggest/core/suggest.cpp @@ -163,9 +163,14 @@ int Suggest::outputSuggestions(DicTraverseSession *traverseSession, int *frequen terminalDicNode->getFlags(), terminalDicNode->getAttributesPos()); const bool isPossiblyOffensiveWord = terminalDicNode->getProbability() <= 0; const bool isExactMatch = terminalDicNode->isExactMatch(); + const bool isFirstCharUppercase = terminalDicNode->isFirstCharUppercase(); + // Heuristic: We exclude freq=0 first-char-uppercase words from exact match. + // (e.g. "AMD" and "and") + const bool isSafeExactMatch = isExactMatch + && !(isPossiblyOffensiveWord && isFirstCharUppercase); const int outputTypeFlags = - isPossiblyOffensiveWord ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0 - | isExactMatch ? Dictionary::KIND_FLAG_EXACT_MATCH : 0; + (isPossiblyOffensiveWord ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0) + | (isSafeExactMatch ? Dictionary::KIND_FLAG_EXACT_MATCH : 0); // Entries that are blacklisted or do not represent a word should not be output. const bool isValidWord = !terminalAttributes.isBlacklistedOrNotAWord(); diff --git a/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h b/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h new file mode 100644 index 000000000..ec1457455 --- /dev/null +++ b/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_DAEMARU_LEVENSHTEIN_EDIT_DISTANCE_POLICY_H +#define LATINIME_DAEMARU_LEVENSHTEIN_EDIT_DISTANCE_POLICY_H + +#include "char_utils.h" +#include "suggest/policyimpl/utils/edit_distance_policy.h" + +namespace latinime { + +class DamerauLevenshteinEditDistancePolicy : public EditDistancePolicy { + public: + DamerauLevenshteinEditDistancePolicy(const int *const string0, const int length0, + const int *const string1, const int length1) + : mString0(string0), mString0Length(length0), mString1(string1), + mString1Length(length1) {} + ~DamerauLevenshteinEditDistancePolicy() {} + + AK_FORCE_INLINE float getSubstitutionCost(const int index0, const int index1) const { + const int c0 = toBaseLowerCase(mString0[index0]); + const int c1 = toBaseLowerCase(mString1[index1]); + return (c0 == c1) ? 0.0f : 1.0f; + } + + AK_FORCE_INLINE float getDeletionCost(const int index0, const int index1) const { + return 1.0f; + } + + AK_FORCE_INLINE float getInsertionCost(const int index0, const int index1) const { + return 1.0f; + } + + AK_FORCE_INLINE bool allowTransposition(const int index0, const int index1) const { + const int c0 = toBaseLowerCase(mString0[index0]); + const int c1 = toBaseLowerCase(mString1[index1]); + if (index0 > 0 && index1 > 0 && c0 == toBaseLowerCase(mString1[index1 - 1]) + && c1 == toBaseLowerCase(mString0[index0 - 1])) { + return true; + } + return false; + } + + AK_FORCE_INLINE float getTranspositionCost(const int index0, const int index1) const { + return getSubstitutionCost(index0, index1); + } + + AK_FORCE_INLINE int getString0Length() const { + return mString0Length; + } + + AK_FORCE_INLINE int getString1Length() const { + return mString1Length; + } + + private: + DISALLOW_COPY_AND_ASSIGN (DamerauLevenshteinEditDistancePolicy); + + const int *const mString0; + const int mString0Length; + const int *const mString1; + const int mString1Length; +}; +} // namespace latinime + +#endif // LATINIME_DAEMARU_LEVENSHTEIN_EDIT_DISTANCE_POLICY_H diff --git a/native/jni/src/suggest/policyimpl/utils/edit_distance.h b/native/jni/src/suggest/policyimpl/utils/edit_distance.h new file mode 100644 index 000000000..cbbd66894 --- /dev/null +++ b/native/jni/src/suggest/policyimpl/utils/edit_distance.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_EDIT_DISTANCE_H +#define LATINIME_EDIT_DISTANCE_H + +#include "defines.h" +#include "suggest/policyimpl/utils/edit_distance_policy.h" + +namespace latinime { + +class EditDistance { + public: + // CAVEAT: There may be performance penalty if you need the edit distance as an integer value. + AK_FORCE_INLINE static float getEditDistance(const EditDistancePolicy *const policy) { + const int beforeLength = policy->getString0Length(); + const int afterLength = policy->getString1Length(); + float dp[(beforeLength + 1) * (afterLength + 1)]; + for (int i = 0; i <= beforeLength; ++i) { + dp[(afterLength + 1) * i] = i * policy->getInsertionCost(i - 1, -1); + } + for (int i = 0; i <= afterLength; ++i) { + dp[i] = i * policy->getDeletionCost(-1, i - 1); + } + + for (int i = 0; i < beforeLength; ++i) { + for (int j = 0; j < afterLength; ++j) { + dp[(afterLength + 1) * (i + 1) + (j + 1)] = min( + dp[(afterLength + 1) * i + (j + 1)] + policy->getInsertionCost(i, j), + min(dp[(afterLength + 1) * (i + 1) + j] + policy->getDeletionCost(i, j), + dp[(afterLength + 1) * i + j] + + policy->getSubstitutionCost(i, j))); + if (policy->allowTransposition(i, j)) { + dp[(afterLength + 1) * (i + 1) + (j + 1)] = min( + dp[(afterLength + 1) * (i + 1) + (j + 1)], + dp[(afterLength + 1) * (i - 1) + (j - 1)] + + policy->getTranspositionCost(i, j)); + } + } + } + if (DEBUG_EDIT_DISTANCE) { + AKLOGI("IN = %d, OUT = %d", beforeLength, afterLength); + for (int i = 0; i < beforeLength + 1; ++i) { + for (int j = 0; j < afterLength + 1; ++j) { + AKLOGI("EDIT[%d][%d], %f", i, j, dp[(afterLength + 1) * i + j]); + } + } + } + return dp[(beforeLength + 1) * (afterLength + 1) - 1]; + } + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(EditDistance); +}; +} // namespace latinime + +#endif // LATINIME_EDIT_DISTANCE_H diff --git a/native/jni/src/suggest/policyimpl/utils/edit_distance_policy.h b/native/jni/src/suggest/policyimpl/utils/edit_distance_policy.h new file mode 100644 index 000000000..e3d1792cb --- /dev/null +++ b/native/jni/src/suggest/policyimpl/utils/edit_distance_policy.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_EDIT_DISTANCE_POLICY_H +#define LATINIME_EDIT_DISTANCE_POLICY_H + +#include "defines.h" + +namespace latinime { + +class EditDistancePolicy { + public: + virtual float getSubstitutionCost(const int index0, const int index1) const = 0; + virtual float getDeletionCost(const int index0, const int index1) const = 0; + virtual float getInsertionCost(const int index0, const int index1) const = 0; + virtual bool allowTransposition(const int index0, const int index1) const = 0; + virtual float getTranspositionCost(const int index0, const int index1) const = 0; + virtual int getString0Length() const = 0; + virtual int getString1Length() const = 0; + + protected: + EditDistancePolicy() {} + virtual ~EditDistancePolicy() {} + + private: + DISALLOW_COPY_AND_ASSIGN(EditDistancePolicy); +}; +} // namespace latinime + +#endif // LATINIME_EDIT_DISTANCE_POLICY_H |