Asearchの構造を把握する
from takker-sprint@2020-09-week1
asearchの構造を把握する
解説
/nota-techconf/本当に役立つFAQ検索システムを目指して#6049e61eadf4e700007d1eef
一番わかりやすい
図解入り
具体例が複数ある
/masui/曖昧検索asearch
この解説を読んだだけではわからない
少しずつ自分の言葉で置き換えながら、何をやっているのか把握する必要がある
/nishio/Bitapアルゴリズム
ExpandHelpの論文
似たような仕組みの解説が載っている
目的
asearchの仕組みを理解する
曖昧度やマッチした位置を取得できないだろうか?
fizzSearchの改善に使う
2021-02-04 18:56:56 ↓は検索対象の先頭と末尾に を含めることで解決した
from /villagepump/scrapboxのリンクサジェスト、とても速くないか?#5f62f27edd59fe0000592213
/icons/hr.icon
ちょっと気になった
部分検索ができているのか?
jabascriptでJavaScriptにマッチさせることが出来るが、javaではマッチしないかもしれない
試してみる
方法
UserScriptにESModulesのimport構文を載せる
これで、developer toolのconsole画面から操作できるようになるはず
無理だった
直接自分のページにclassをベタ打ちすることにした
08:37:13 どのみち、consoleからは使えないようだ
仕方ないので、テストコードもベタ打ちする。
テストで使ったcode
code:script.js
class Asearch {
get INITPAT() {return 0x80000000;} // 0100,0000,0000,0000,0000,0000,0000,0000
get MAXCHAR() {return 0x100;}
get INITSTATE() {return this.INITPAT, 0, 0, 0;}
constructor(source) {
this.source = source;
this.shiftpat = Array(this.MAXCHAR).map(_ => 0);
this.epsilon = 0;
let mask = this.INITPAT;
const ref = this.unpack(this.source);
for (const item of ref) {
// 0x20 is a space
if (item === 0x20) {
this.epsilon |= mask;
} else {
this.shiftpatitem |= mask;
this.shiftpatthis.toupper(item) |= mask;
this.shiftpatthis.tolower(item) |= mask;
mask >>>= 1;
}
}
this.acceptpat = mask;
return this;
}
isupper(c) {
// 0x41 = A, 0x5a = Z
return (c >= 0x41) && (c <= 0x5a);
}
islower(c) {
// 0x61 = a, 0x7a = z
return (c >= 0x61) && (c <= 0x7a);
}
tolower(c) {
return this.isupper(c) ? c + 0x20 : c;
}
toupper(c) {
return this.islower(c) ? c - 0x20 : c;
}
state(state = this.INITSTATE, str = '') {
let i0 = state0;
let i1 = state1;
let i2 = state2;
let i3 = state3;
const ref = this.unpack(str);
for (const item of ref) {
const mask = this.shiftpatitem;
i3 = (i3 & this.epsilon) | ((i3 & mask) >>> 1) | (i2 >>> 1) | i2;
i2 = (i2 & this.epsilon) | ((i2 & mask) >>> 1) | (i1 >>> 1) | i1;
i1 = (i1 & this.epsilon) | ((i1 & mask) >>> 1) | (i0 >>> 1) | i0;
i0 = (i0 & this.epsilon) | ((i0 & mask) >>> 1);
i1 |= i0 >>> 1;
i2 |= i1 >>> 1;
i3 |= i2 >>> 1;
}
return i0, i1, i2, i3;
}
match(str, ambig = 0) {
const s = this.state(this.INITSTATE, str);
if (!(ambig < this.INITSTATE.length)) {
ambig = this.INITSTATE.length - 1;
}
return (sambig & this.acceptpat) !== 0;
}
unpack(str) {
let bytes = [];
str.split('')
.map(item => item.charCodeAt(0))
.forEach(code => {
if (code > 0xFF) {
bytes.push((code & 0xFF00) >>> 8);
}
bytes.push(code & 0xFF);
});
return bytes;
}
}
const target = 'Javascript';
const test_a = new Asearch(target);
const words = 'javascript', 'jabascript', 'javacript', 'java';
console.log('Asearch test:');
for (const word of words) {
const range = n => ...Array(n).keys();
for (const ambig of range(4)){
console.log(${word} matches ${target}? : ${test_a.match(word,ambig)} (ambig = ${ambig}));
}
}
08:44:44 結果
やっぱ部分一致はしないようだ
https://gyazo.com/992c974687c4516d97f9ea2e0b453f6c
#2021-10-09 18:04:12
#2021-04-14 23:01:46
#2021-02-04 18:59:48
#2020-10-13 00:54:56
#2020-09-16 07:21:33
#2020-09-14 08:30:54
#2020-09-03 10:29:16