Skip to content

Commit

Permalink
Suggestion making code overhaul! (#42)
Browse files Browse the repository at this point in the history
* Remove the usage of QMap's.
Set the regex patterns in the constructor and optimize them.
Initialize RegexParser only once.

* Update Database.cpp
Remove duplicates

* Show AutoCorrect suggestion at first.

* Call sorting function inline.
  • Loading branch information
mominul authored Jun 14, 2018
1 parent 47edf47 commit 1db386d
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 72 deletions.
7 changes: 2 additions & 5 deletions src/engine/libengine/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#include <QRegularExpression>
#include <QStringList>
#include "Database.h"
#include "regexparser.h"
#include "log.h"

Database::Database() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
Expand Down Expand Up @@ -98,10 +96,8 @@ void Database::loadSuffixTableFromDatabase(QSqlDatabase dbase) {

QStringList Database::find(QString word) {
if(word != "") {
RegexParser rgx;
QStringList tablelist;
QStringList suggestions;
char lmc = word.toStdString().at(0); // Left Most Character
QChar lmc = word.at(0); // Left Most Character

QRegularExpression regex(rgx.parse(word));

Expand All @@ -113,6 +109,7 @@ QStringList Database::find(QString word) {
}
}
}
suggestions.removeDuplicates();
return suggestions;
} else {
return {""};
Expand Down
4 changes: 3 additions & 1 deletion src/engine/libengine/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
#include <QString>
#include <QMap>
#include <QVector>
#include "regexparser.h"

class Database {
QMap<QString, QVector<QString>> word_table;
QMap<QString, QString> suffix_table;
QMap<char, QStringList> prefixTableMap;
QMap<QChar, QStringList> prefixTableMap;
RegexParser rgx;
public:
Database();
~Database();
Expand Down
4 changes: 2 additions & 2 deletions src/engine/libengine/MethodPhonetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void MethodPhonetic::setLayout(QJsonObject lay) {
suggest.setLayout(lay);
}

std::vector<std::string> MethodPhonetic::toStdVector(QVector<QString> vec) {
std::vector<std::string> MethodPhonetic::toStdVector(QStringList vec) {
std::vector<std::string> v;
for(auto& str : vec) {
v.push_back(str.toStdString());
Expand All @@ -42,7 +42,7 @@ Suggestion MethodPhonetic::createSuggestion() {
changedCandidateSelection = false;

// Build the suggestions
list = suggest.Suggest(EnglishT).toVector();
list = suggest.Suggest(EnglishT);

prevSelected = 0;

Expand Down
4 changes: 2 additions & 2 deletions src/engine/libengine/MethodPhonetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ class MethodPhonetic : public LayoutMth {
bool changedCandidateSelection = false;
int prevSelected;
PhoneticSuggestion suggest;
QVector<QString> list;
QStringList list;
QString EnglishT;
Suggestion suggested;

Suggestion createSuggestion();
std::vector<std::string> toStdVector(QVector<QString> vec);
std::vector<std::string> toStdVector(QStringList vec);
public:
// Functions inherited from class LayoutMth
void setLayout(QJsonObject lay);
Expand Down
108 changes: 53 additions & 55 deletions src/engine/libengine/PhoneticSuggestion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,24 @@
#include "Settings.h"
#include "qlevenshtein.hpp"

PhoneticSuggestion::PhoneticSuggestion() {}
PhoneticSuggestion::PhoneticSuggestion() {
// Set patterns and optimize them
rgxPadding.setPattern("(^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*?(?=(?:,{2,}))|^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*)(.*?(?:,,)*)((?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*$)");
rgxKar.setPattern("^[\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc\u09c4]$");
rgxVowel.setPattern("^[\u0985\u0986\u0987\u0988\u0989\u098a\u098b\u098f\u0990\u0993\u0994\u098c\u09e1\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc]$");
rgxPadding.optimize();
rgxKar.optimize();
rgxVowel.optimize();
}

void PhoneticSuggestion::setLayout(QJsonObject lay) {
parser.setLayout(lay);
}

QStringList PhoneticSuggestion::getDictionarySuggestion(QMap<QString, QString> splitWord) {
QStringList PhoneticSuggestion::getDictionarySuggestion() {
QStringList words;

QString key = splitWord["middle"].toLower();
QString key = padMiddle.toLower();

if (phoneticCache.contains(key)) {
words = phoneticCache[key];
Expand All @@ -39,7 +47,7 @@ QStringList PhoneticSuggestion::getDictionarySuggestion(QMap<QString, QString> s
return words;
}

QString PhoneticSuggestion::getAutocorrect(QString word, QMap<QString, QString> splitWord) {
QString PhoneticSuggestion::getAutocorrect(QString word) {
QString corrected;

QString autoCorrect = autodict.getCorrected(parser.fixString(word));
Expand All @@ -51,7 +59,7 @@ QString PhoneticSuggestion::getAutocorrect(QString word, QMap<QString, QString>
corrected = parser.parse(autoCorrect);
}
} else {
QString withCorrection = autodict.getCorrected(splitWord["middle"]);
QString withCorrection = autodict.getCorrected(padMiddle);
if (withCorrection != "") {
corrected = parser.parse(withCorrection);
}
Expand All @@ -60,48 +68,29 @@ QString PhoneticSuggestion::getAutocorrect(QString word, QMap<QString, QString>
return corrected;
}

QMap<QString, QString> PhoneticSuggestion::separatePadding(QString word) {
QMap<QString, QString> cutted;
QRegularExpression rgx("(^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*?(?=(?:,{2,}))|^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*)(.*?(?:,,)*)((?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*$)");
QRegularExpressionMatch match = rgx.match(word);
void PhoneticSuggestion::separatePadding(QString word) {
QRegularExpressionMatch match = rgxPadding.match(word);
if(match.hasMatch()) {
cutted["begin"] = match.captured(1);
cutted["middle"] = match.captured(2);
cutted["end"] = match.captured(3);
padBegin = match.captured(1);
padMiddle = match.captured(2);
padEnd = match.captured(3);
}
return cutted;
}

QStringList PhoneticSuggestion::sortByPhoneticRelevance(QString phonetic, QStringList dictSuggestion) {
std::sort(dictSuggestion.begin(), dictSuggestion.end(), [&] (QString i, QString j) {
int dist1 = levenshtein_distance(phonetic, i);
int dist2 = levenshtein_distance(phonetic, j);
if(dist1 < dist2) {
return true;
} else if(dist1 > dist2) {
return false;
} else {
return true;
}
});

return dictSuggestion;
}

bool PhoneticSuggestion::isKar(QString word) {
if (word.length() < 1) {
return false;
}

return word.left(1).contains(QRegularExpression("^[\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc\u09c4]$"));
return word.left(1).contains(rgxKar);
}

bool PhoneticSuggestion::isVowel(QString word) {
if (word.length() < 1) {
return false;
}

return word.left(1).contains(QRegularExpression("^[\u0985\u0986\u0987\u0988\u0989\u098a\u098b\u098f\u0990\u0993\u0994\u098c\u09e1\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc]$"));
return word.left(1).contains(rgxVowel);
}

void PhoneticSuggestion::appendIfNotContains(QStringList &array, QString item) {
Expand All @@ -116,10 +105,10 @@ void PhoneticSuggestion::addToTempCache(QString full, QString base, QString eng)
}
}

QStringList PhoneticSuggestion::addSuffix(QMap<QString, QString> splitWord) {
QStringList PhoneticSuggestion::addSuffix() {
QStringList tempList;
QString fullWord;
QString dictKey = splitWord["middle"].toLower();
QString dictKey = padMiddle.toLower();
int len = dictKey.length();

QStringList rList;
Expand Down Expand Up @@ -171,7 +160,7 @@ QStringList PhoneticSuggestion::addSuffix(QMap<QString, QString> splitWord) {

QString PhoneticSuggestion::getPrevSelected() {
QString selected;
QString word = PadMap["middle"];
QString word = padMiddle;
int len = word.length();

if (cacheMan.getCandidateSelection(word) != "") {
Expand Down Expand Up @@ -210,33 +199,44 @@ QString PhoneticSuggestion::getPrevSelected() {
}
}

return PadMap["begin"] + selected + PadMap["end"];
return padBegin + selected + padEnd;
}

QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic, QMap<QString, QString> splitWord) {
QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic) {
QStringList words;

// Sort dictionary suggestion
std::sort(dictSuggestion.begin(), dictSuggestion.end(), [&] (QString i, QString j) {
int dist1 = levenshtein_distance(phonetic, i);
int dist2 = levenshtein_distance(phonetic, j);
if(dist1 < dist2) {
return true;
} else if(dist1 > dist2) {
return false;
} else {
return true;
}
});

if (autoCorrect != "") {
words.append(autoCorrect);
if (autoCorrect != writtenWord) {
dictSuggestion.append(autoCorrect);
dictSuggestion.prepend(autoCorrect);
}
}

if (phoneticCache[splitWord["middle"].toLower()].isEmpty()) {
if (phoneticCache[padMiddle.toLower()].isEmpty()) {
if (!dictSuggestion.isEmpty()) {
phoneticCache[splitWord["middle"].toLower()] = dictSuggestion;
phoneticCache[padMiddle.toLower()] = dictSuggestion;
}
}

QStringList dictSuggestionWithSuffix = addSuffix(splitWord);
QStringList dictSuggestionWithSuffix = addSuffix();

for (auto& word : dictSuggestionWithSuffix) {
appendIfNotContains(words, word);
}

words = sortByPhoneticRelevance(phonetic, words);

appendIfNotContains(words, phonetic);

prevSuggestion << words;
Expand All @@ -245,40 +245,38 @@ QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString auto
// smiley rule
if (autoCorrect == writtenWord) {
if (autoCorrect != word) {
word = splitWord["begin"] + word + splitWord["end"];
word = padBegin + word + padEnd;
}
} else {
word = splitWord["begin"] + word + splitWord["end"];
word = padBegin + word + padEnd;
}
}

return words;
}

void PhoneticSuggestion::saveSelection(int index) {
cacheMan.writeCandidateSelection(PadMap["middle"], prevSuggestion[index]);
cacheMan.writeCandidateSelection(padMiddle, prevSuggestion[index]);
}

QStringList PhoneticSuggestion::Suggest(QString word) {
QStringList suggestion;
QMap<QString, QString> splitWord = separatePadding(word);
separatePadding(word);
prevSuggestion.clear();

splitWord["begin"] = parser.parse(splitWord["begin"]);
splitWord["end"] = parser.parse(splitWord["end"]);

PadMap = splitWord;
padBegin = parser.parse(padBegin);
padEnd = parser.parse(padEnd);

QString phonetic = parser.parse(splitWord["middle"]);
QString phonetic = parser.parse(padMiddle);

if(!gSettings->getShowCWPhonetic()) {
// Return only phonetic suggestion
suggestion.append(splitWord["begin"] + phonetic + splitWord["end"]);
suggestion.append(padBegin + phonetic + padEnd);
} else {
QStringList dictSuggestion = getDictionarySuggestion(splitWord);
QString autoCorrect = getAutocorrect(word, splitWord);
QStringList dictSuggestion = getDictionarySuggestion();
QString autoCorrect = getAutocorrect(word);

suggestion = joinSuggestion(word, autoCorrect, dictSuggestion, phonetic, splitWord);
suggestion = joinSuggestion(word, autoCorrect, dictSuggestion, phonetic);
}

return suggestion;
Expand Down
17 changes: 10 additions & 7 deletions src/engine/libengine/PhoneticSuggestion.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,23 @@ class PhoneticSuggestion {
Database db;
CacheManager cacheMan;

QMap<QString, QString> PadMap;
QRegularExpression rgxPadding;
QRegularExpression rgxKar;
QRegularExpression rgxVowel;

QString padBegin, padMiddle, padEnd;
QMap<QString, QStringList> phoneticCache;
QMap<QString, Cache> tempCache;
QStringList prevSuggestion;

QMap<QString, QString> separatePadding(QString word);
void separatePadding(QString word);
bool isKar(QString word);
bool isVowel(QString word);
QStringList joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic, QMap<QString, QString> splitWord);
QStringList joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic);
void appendIfNotContains(QStringList &array, QString item);
QStringList sortByPhoneticRelevance(QString phonetic, QStringList dictSuggestion);
QStringList getDictionarySuggestion(QMap<QString, QString> splitWord);
QString getAutocorrect(QString word, QMap<QString, QString> splitWord);
QStringList addSuffix(QMap<QString, QString> splitWord);
QStringList getDictionarySuggestion();
QString getAutocorrect(QString word);
QStringList addSuffix();
void addToTempCache(QString full, QString base, QString eng);

public:
Expand Down

0 comments on commit 1db386d

Please sign in to comment.