Здравствуйте, vdimas, Вы писали:
V>Есть набор из названий брендов (озвучено — порядка миллиона).
V>Есть входная строка, например "планшет Samsung"
V>Необходимо без ИИ сопоставить бренд из словаря этой строке.
V>Затем даётся дополнительное ТЗ — необходимо сделать поиск нечётким, т.е. с возможными опечатками.
Взял
PEG.js:
В словаре слово: samsung
Возможные опечатки: u->a | a->u | u->y | y->u
Входные строки вида: samsung samsyng sumsyng
| | Грамматика |
| | /*
В словаре слово: samsung
Возможные опечатки: u->a | a->u | u->y | y->u
Входные строки вида: samsung samsyng sumsyng
*/
{
options.dictionary = {};
options.typo = {};
var add = (dictionary, text)=>{
var obj = dictionary;
(text+'.').split('').forEach(_=>{
var next = obj[_];
obj = next = next?next:(obj[_]={});
});
}
add(options.dictionary, "samsung");
add(options.typo, "ua");
add(options.typo, "au");
add(options.typo, "uy");
add(options.typo, "yu");
console.log(options.typo);
options.next = (ctx,sym)=>{
console.log('next:',JSON.stringify(ctx),sym);
if (!ctx.tss.length) return false;
var addts = [];
ctx.tss = ctx.tss.flatMap(_=>{
if (!_.ts) { return []; }
var nnts = {ts:_.ts,res:_.res,orig:_.orig,typos:_.typos};
_.ts = _.ts[sym];
_.res = _.ts ? _.res + sym : '';
_.orig = _.ts ? _.orig + sym : '';
{
var tsym = options.typo[sym];
if (tsym != undefined) {
var variants = Object.keys(tsym)
variants.forEach(v=>{
var nts = {ts:nnts.ts,res:nnts.res,orig:nnts.orig,typos:nnts.typos};
nts.ts = nts.ts[v];
nts.orig = nts.ts ? nts.orig + sym : '';
nts.res = nts.ts ? nts.res + v : '';
++nts.typos;
if (nts.ts) {
addts.push(nts);
}
});
}
}
return _.ts ? _ : [];
}).concat(addts);
return !!ctx.tss.length;
}
options.valid = (ctx)=>{
if (!ctx.tss.length) return false;
ctx.tss = ctx.tss.map(_=>undefined != _.ts['.']?_:null).filter(_=>_);
return !!ctx.tss.length;
}
}
words = (word _)+
ctx = &(.) {return {tss:[{ts:options.dictionary, res:'',orig:'',typos:0}]};}
word = ctx:ctx word:(s:[a-z] &{return options.next(ctx,s);} {return s;})+ &{return options.valid(ctx);} { return ctx;}
_ = [ \t\r\n]*
|
| | |
Нужно подготовить два словаря: брендов и опечаток.
Миллион для таких словарей не много, должно потянуть.
По идее, работает достаточно быстро.