-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpellChecker.cpp
More file actions
118 lines (98 loc) · 2.57 KB
/
SpellChecker.cpp
File metadata and controls
118 lines (98 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//(C) 2020, dan-gubkin@mail.ru
#include "Constants.hpp"
#include "SpellChecker.hpp"
#include <fstream>
#include <string>
#include <algorithm>
#include <iostream>
#include <cstring>
bool SpellChecker::correct(const char* word, Dictionary& dict, Result& res){
const auto j = dict.find( word );
if ( j!=dict.end() ){
return true;
}
Candidates cnd[2]; // 0 - add; 1- del
edits_add(std::string(word), cnd[0], -1);
edits_del(std::string(word), cnd[1], -1);
bool found = false;
for (size_t k=0; k<2; k++){
for(auto i=cnd[k].begin(); i!=cnd[k].end(); i++){
const auto j = dict.find( i->first.c_str() );
if (j!=dict.end()){
found = true;
res.insert({j->second, j->first});
}
}
}
if (found){
return false;
}
Candidates second;
edits_second(cnd[0], cnd[1], second);
found = false;
for(auto i=second.begin(); i!=second.end(); i++){
const auto j = dict.find( i->first.c_str() );
if (j!=dict.end()){
found = true;
res.insert({j->second, j->first});
}
}
return false;
}
static inline bool check_except_del(ssize_t except, size_t i){
if (except == -1){
return false;
}
if ( except == (ssize_t)i || except+1 == (ssize_t)i || except-1 == (ssize_t)i){
return true;
}
return false;
}
static inline bool check_except_add(ssize_t except, size_t i){
if (except == -1){
return false;
}
if ( except == (ssize_t)i || except+1 == (ssize_t)i){
return true;
}
return false;
}
void SpellChecker::edits_del(const std::string& word, Candidates& cnd, ssize_t except){
std::string::size_type w_len = word.size();
if (w_len<2 || w_len>MAX_WORD_LEN){
return;
}
for (std::string::size_type i = 0; i < word.size(); i++){
if (check_except_del(except, i)){
continue;
}
std::string copy = word.substr(0, i) + word.substr(i+1);
cnd.insert( {copy, i} ); //deletions
}
}
void SpellChecker::edits_add(const std::string& word, Candidates& cnd, ssize_t except){
std::string::size_type w_len = word.size();
if (w_len>=MAX_WORD_LEN){
return;
}
for (size_t i = 0; i <= w_len; i++){
if (check_except_add(except, i)){
continue;
}
for (char ch = 'a'; ch <= 'z'; ch++){
std::string copy = word.substr(0,i) + ch + word.substr(i);
cnd.insert( {copy, i} ); //insertion
}
}
}
void SpellChecker::edits_second(const Candidates& add, const Candidates& del, Candidates& res){
for (auto j = add.begin(); j!=add.end(); j++){
std::string word = j->first;
edits_del(word, res, -1);
edits_add(word, res, (ssize_t)j->second);
}
for (auto j = del.begin(); j!=del.end(); j++){
std::string word = j->first;
edits_del(word, res, (ssize_t)j->second);
}
}