英語文書の地味な濾過装置を紹介します。固定辞書に登録された文字列を1文字に置換していき、縮んだ分は末尾に空白が埋め込んでいきます。結果として圧縮しやすい文字列が生成されるかもしれないという代物。
符号130~250は辞書番号に該当し、254はescape符号で辞書番号自体を符号化する為に用います。
const wordList="0ac0ad0ai0al0am0an0ar0as0at0ea0ec0ed0ee0el0en0er0es0et0id0ie0ig0il0in0io0is0it0of0ol0on0oo0or0os0ou0ow0ul0un0ur0us0ba0be0ca0ce0co0ch0de0di0ge0gh0ha0he0hi0ho0ra0re0ri0ro0rs0la0le0li0lo0ld0ll0ly0se0si0so0sh0ss0st0ma0me0mi0ne0nc0nd0ng0nt0pa0pe0ta0te0ti0to0th0tr0wa0ve0all0and0but0dow0for0had0hav0her0him0his0man0mor0not0now0one0out0she0the0was0wer0whi0whe0wit0you0any0are0that0said0with0have0this0from0were0tion".split(0);
function MakeWordTree(W,e){
for(var i=256,j,c,p,s=130,l=W.length,n=1,T=[],I=[];i;)T[--i]=[];
for(;++i<l;I[T[p].s=s++]=i)
for(j=p=0;c=W[i].charCodeAt(j++);)
p=T[p][c-=97]?T[p][c]:T[p][c]=n++;
I.cs=s;return e?T:I
}
/*
engCuting(A,B,size)
@A :要素が0~255の数値配列
@B :変換先配列. A==Bでも良いが,Aは上書きされる
@size :Aの配列長. 省略するとA.lengthを採用
返値 :要素が0~255の数値配列
engCuted(A,size)
@A :要素が0~255の数値配列
@size :Aの配列長. 省略するとA.lengthを採用
返値 :要素が0~255の数値配列
*/
function engCuting(A,B,size){
A[size-1]>-1||(size=A.length);
if(size<8)return;
var i=0,j,p=0,o=0,a,O=[],T=MakeWordTree(wordList,1);
for(size-=5;i<size;){
if(o>size-11)return;
if(A[i]>96&&A[i]<123){
for(var s=0,l=p=j=0;a=A[i+j++]-97>>>0,a<26&&T[p][a];)T[p=T[p][a]].s&&(s=T[p].s,l=j);
if(s){O[o++]=s;i+=l;continue}
O[o++]=A[i++];
}else A[i]>129&&(O[o++]=254),O[o++]=A[i++],p=0
}
for(size+=5;i<size;O[o++]=A[i++])if(A[i]>129)O[o++]=254;
if(o>size*0.9)return;
for(i=o;i++<size;)O[o++]=32;
B instanceof Array||(B=Array(size));
for(;o;)B[--o]=O[o];
return B
}
function engCuted(A,size){
A[size-1]>-1||(size=A.length);
for(var i=0,j,o=0,p,c,O=[],W=wordList,I=MakeWordTree(W),m=I.cs;o<size;)
if((c=A[i++])>129&&c<m)
for(p=I[c],j=0;(c=W[p].charCodeAt(j++))&&o<size;)O[o++]=c;
else if(c===254&&i<size&&A[i]>129)O[o++]=A[i++];
else O[o++]=c;
return O
}
使用例
let A=Array.from("That that is is that that is not is not is that it it is",a=>a.charCodeAt());
let e=engCuting(A,null), d=engCuted(e)
console.log(e,d)