fix(输入法): 优化双端联想排序并消除文字刷新闪烁
这个提交包含在:
1 父节点
bce6f8083b
当前提交
b95e7caae7
31 个文件已更改
+504
-124
没有与搜索条件相匹配的文件
@@ -7,6 +7,40 @@ T9 = {letter: str(i + 2) for i, group in enumerate(GROUPS) for letter in group}
|
||||
GROUPS14 = ['qw','er','ty','ui','op','as','df','gh','jk','l','zx','cv','bn','m']
|
||||
KEY14 = {letter: '0123456789abcd'[i] for i, group in enumerate(GROUPS14) for letter in group}
|
||||
|
||||
def predictive_bucket(value):
|
||||
result=0
|
||||
for ch in value:result=(result*31+ord(ch))&0xffff
|
||||
return format(result%256,'02x')
|
||||
|
||||
def associations(entries,frequencies):
|
||||
"""Derive bounded word continuations from licensed phrases; no user corpus."""
|
||||
result={}
|
||||
for word in {word for words in entries.values()for word in words}:
|
||||
frequency=frequencies.get(word,0)
|
||||
if frequency<20 or not re.fullmatch(r'[\u3400-\u9fff]{2,12}',word):continue
|
||||
for cut in range(1,min(4,len(word)-1)+1):
|
||||
prefix,suffix=word[:cut],word[cut:]
|
||||
result.setdefault(prefix,{})[suffix]=round(frequency/(1+.25*len(suffix)))
|
||||
# Small, original conversational defaults supplement dictionary word splits.
|
||||
seeds=json.loads((APP/'src/common/association-seeds.json').read_text(encoding='utf-8'))
|
||||
for prefix,words in seeds.items():
|
||||
for rank,word in enumerate(words):result.setdefault(prefix,{})[word]=200000-rank*10000
|
||||
return {prefix:sorted(words.items(),key=lambda x:(-x[1],x[0]))[:8]for prefix,words in sorted(result.items())}
|
||||
|
||||
def completions(entries,frequencies):
|
||||
result={}
|
||||
for key,words in entries.items():
|
||||
for mode,code in [('py',key),('t9',''.join(T9[ch]for ch in key)),('14',''.join(KEY14[ch]for ch in key))]:
|
||||
for length in range(2,min(3 if mode!='14'else 2,len(code)-1)+1):
|
||||
if len(code)-length>4:continue
|
||||
target=result.setdefault(mode+':'+code[:length],{})
|
||||
for ordinal,word in enumerate(words):
|
||||
frequency=frequencies.get(word,0)
|
||||
if frequency<20:continue
|
||||
value=[word,key,frequency,ordinal]
|
||||
if word not in target or target[word][2]<frequency:target[word]=value
|
||||
return {prefix:sorted(words.values(),key=lambda x:(-x[2],len(x[1]),x[3],x[0]))[:12]for prefix,words in sorted(result.items())}
|
||||
|
||||
def from94(value):
|
||||
number = 0
|
||||
for ch in value:
|
||||
@@ -57,6 +91,11 @@ def convert(source, target):
|
||||
output=target/(name+'.json')
|
||||
data=json.dumps({'entries':content,'frequencies':weights}, ensure_ascii=False, separators=(',', ':')).encode('utf-8')
|
||||
if not output.exists() or output.read_bytes()!=data:output.write_bytes(data)
|
||||
association_shards={};completion_shards={}
|
||||
for prefix,items in associations(entries,frequencies).items():association_shards.setdefault('a'+predictive_bucket(prefix),{})[prefix]=items
|
||||
for prefix,items in completions(entries,frequencies).items():completion_shards.setdefault('c'+predictive_bucket(prefix),{})[prefix]=items
|
||||
for name,content in {**association_shards,**completion_shards}.items():
|
||||
(target/(name+'.json')).write_text(json.dumps(content,ensure_ascii=False,separators=(',',':')),encoding='utf-8',newline='\n')
|
||||
# Every original candidate remains accessible, in original per-key order.
|
||||
restored = {};restored14={}
|
||||
for name in shards:
|
||||
@@ -69,6 +108,8 @@ def convert(source, target):
|
||||
t9_shards=sum(not name.startswith('d')for name in shards),
|
||||
key14_shards=sum(name.startswith('d')for name in shards),key14_groups=GROUPS14,key14_prefix_length=3,
|
||||
largest_shard_bytes=max((target/(name+'.json')).stat().st_size for name in shards),
|
||||
association_shards=sorted(association_shards),completion_shards=sorted(completion_shards),
|
||||
predictive_largest_shard_bytes=max((target/(name+'.json')).stat().st_size for name in [*association_shards,*completion_shards]),
|
||||
source_files={name:hashlib.sha256(data).hexdigest() for name,data in sorted(files.items())})
|
||||
if frequency_path.exists():report['t9_frequency_source']={'project':'jieba 0.42.1','license':'MIT','sha256':hashlib.sha256(frequency_path.read_bytes()).hexdigest()}
|
||||
output=target/'meta.json';data=(json.dumps(report, ensure_ascii=False, indent=2)+'\n').encode('utf-8')
|
||||
|
||||
在新工单中引用
屏蔽一个用户