关于输入法重码率的计算

本人在电脑上一直使用的86版五笔输入法。在手机上之前使用的是9宫全拼,后来使用了基于Rime框架的同文输入法,没有九宫全拼了;然后就自己配置了一个四角号码输入法

如果有兴趣的可以移步:四角号码输入法介绍四角号码配置仓库

四角号码输入法用下来感觉还是不错的,使用九宫格键盘,按键大,不易误触。
Snipaste_2025-05-07_13-03-27

在调查四角号码输入法可行性的时候,也考虑和计算了重码率这个概念。统计的思路是统计码表内的总字数作为基准,计算存在同码字的字数,与之相除得到的比例值作为重码率。所使用的码表文件见: 四角号码码表 四码+五码+六码 收录汉字及部件约 7w5 个

统计脚本

统计码表的重码率 python 脚本如下:

# -*- coding:UTF-8 -*-
"""
@author: dyy
@contact: douyaoyuan@126.com
@time: 2025/4/18 12:01
@file: 字典组词方案验证.py
@desc: xxxxxx
"""

# region 引入必要的依赖
import os

模块名 = 'DebugInfo'
try:
    from DebugInfo.DebugInfo import *
except ImportError as impErr:
    print(f"尝试导入 {模块名} 依赖时检测到异常:{impErr}")
    print(f"尝试安装 {模块名} 模块:")
    try:
        os.system(f"pip install {模块名}")
    except OSError as osErr:
        print(f"尝试安装模块 {模块名} 时检测到异常:{osErr}")
        exit(0)
    else:
        try:
            from DebugInfo.DebugInfo import *
        except ImportError as impErr:
            print(f"再次尝试导入 {模块名} 依赖时检测到异常:{impErr}")
            exit(0)

# endregion

class CharCls:
    word: str = ''
    code: str = ''

def 加载码表(charCodeFile_: str,
             colIdxOfCode: int = 0,
             限制码长: int = 0,
             画板: 打印模板 = None)-> dict[str, CharCls]:
    """
    加载指定的码表文档,默认第一列为字,不同列以 tab 分隔
    :param colIdxOfCode: 编码所在的列,如果小于1,则默认最后一列为编码
    :param charCodeFile_: 指定的码表文档,文本文档
    :param 限制码长: 限制码的长度,如果为0,则不限制
    :param 画板: 打印模板
    :return: 返回码表字典,以字为key,以 CharCls对象为值
    """
    画板 = 画板 if isinstance(画板, 打印模板) else 打印模板()
    画板.执行位置(加载码表)

    if not charCodeFile_:
        画板.提示错误('未指定字码文件')
        return {}
    if not os.path.isfile(charCodeFile_):
        画板.提示错误(f'指定的字码文件不存在: {黄字(charCodeFile_)}')
        return {}

    charsDic: [str, CharCls] = {}
    with open(charCodeFile_, 'r', encoding='utf-8') as f:
        开始: bool = False
        forin f:=.strip()
            if 开始:
                if not.startswith('#'):
                    行分列: list[str] =.split('\t')
                    if len(行分列) < 2: # 如果行的列数小于2,则这不是有效的字码行
                        continue= 行分列[0]
                    if 0 < colIdxOfCode < len(行分列):= 行分列[colIdxOfCode]
                    else:= 行分列[-1]
                    if 限制码长 > 0:=[:限制码长]
                    if len() > 1:
                        okFlg: bool = True
                        if charsDic.__contains__():
                            if len(charsDic[].code) > len():
                                okFlg = False
                        if okFlg:
                            cc: CharCls = CharCls()
                            cc.word = 字
                            cc.code = 码

                            charsDic[] = cc
            if== '...':
                开始 = True

    return charsDic

def 加载词表(wordFile_: str, 画板: 打印模板 = None) -> dict[str, CharCls]:
    """
    加载指定的词语表,词语位于第一列,不同列以 Tab 分隔;可限制词语的字数,加载词语表时,不加载里面的码
    :param wordFile_: 指定的词语表文档
    :param 画板: 打印模板
    :return: 返回词码字典
    """
    画板 = 画板 if isinstance(画板, 打印模板) else 打印模板()
    画板.执行位置(加载词表)

    if not wordFile_:
        画板.提示错误('未指定词语文件')
        return {}
    if not os.path.isfile(wordFile_):
        画板.提示错误(f'指定的词语文件不存在: {黄字(wordFile_)}')
        return {}

    worldsDict: [str, CharCls] = {}
    with open(wordFile_, 'r', encoding='utf-8') as f:
        开始: bool = False
        forin f:=.strip()
            if 开始:
                if not.startswith('#'):, *_ =.split('\t')
                    if len() == 2 and not worldsDict.__contains__():
                        wc: CharCls = CharCls()
                        wc.world = 词

                        worldsDict[] = wc
            if== '...':
                开始 = True
    return worldsDict

if __name__ == "__main__":
    画板 = 打印模板(True)
    画板.执行位置(__file__)

    # 直接统计码表的重码率
    if True:
        码表: dict[str, CharCls] = 加载码表(charCodeFile_=r'f:\Users\TmpFolder\sjhm_base.dict.yaml',
                                            colIdxOfCode=1,
                                            画板=画板.副本.缩进())
        汉字数量: int = len(码表)
        画板.消息(f'共加载码表条目 {绿字(汉字数量)} 条')

        码字表: dict[str, list[str]] = {}  # 以 码 为键,统计每个码应对的汉字
        for k, v in 码表.items():
            if v.code in 码字表.keys():
                码字表[v.code].append(k)
            else:
                码字表[v.code] = [k]

        重码字数量:int = len([len(码字表[code]) for code in 码字表 if len(码字表[code]) > 1])
        画板.消息(f'存在重码的字共有 {红字(重码字数量)} 个')
        画板.消息(f'计算码码率为 {重码字数量 * 100 / 汉字数量}%')

重码率统计

四角号码最大码表可以是码,但也兼容码和码,以及存在一简、二简、三简字,日常使用一般是一简、二简、三简字和标准四码。

对于一、二、三简字,同时存在其对应的标准四、五、六码编码,在以下的统计中,我们将去除一、二、三简码,只统计四、五、六码的编码条目。

如果一个字的编码存在不同的码长编码,则以较长的码为统计依据。

下面分别统计不限码长和限码长的重码率情况。

不限制码长统计重码率

码表汉字条目为 74162 条,其中存在重码的字为 49313 条,重码率为 66.49%

Snipaste_2025-05-07_13-46-01

限制码长为五码,统计重码率

这里,我们不统计六码编码,只统计码、码的条目,对于六码的条目,我们将其码长截短为码。

码表汉字条目为 74162 条,其中存在重码的字为 65303 条,重码率为 88.05%

Snipaste_2025-05-07_13-46-59

限制码长为四码,统计重码率

这里,我们将码长大于码的条目,其码长截短为码。统计其重码率如下。

码表汉字条目为 74162 条,其中存在重码的字为 72862 条,重码率为 98.25%

Snipaste_2025-05-07_13-49-56

不翻页重码率

在实际的输入法使用中,一般我们在第一页中可以提供最多10个候选项目,在不翻面的情况下,选字是十分快捷和便利的。如果以不翻页选字为标准,即只将重码字数在10以上的字计算为重码字,则以此口径统计重码率如下:

码长类型汉字数量重码字数量重码率
不限码长741621007913.59%
限定5741622952139.81%
限定4741625950780.24%

全拼重码率参考(不限码长)

作为对比,统计全拼的单字重码率数据如下(以四叶草拼音的码表为统计基准)。

码表汉字条目为 26315 条,其中存在重码的字为 26082 条,重码率为 99.11%

Snipaste_2025-05-07_14-00-02

86五笔重码率参考(定长四码)

作为对比,统计86版五笔码表的单字重码率数据如下。

码表汉字条目为 74162 条,其中存在重码的字为 10079 条,重码率为 13.59%

Snipaste_2025-05-07_14-02-22

小结

从以上可以看出,从重码率的角度,四角号码输入法在手机使用场景下,优于全拼,但差于五笔(但五笔需要使用全26键键盘,手机上只有两个大拇指操作,误触率和操作便利性上要比电脑键盘差的多)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

团圆吧

1 分钱,求鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值