【半求助】各个编程语言都有哪些比较成熟的关于中文排序的库或者依赖?

原因

现在在鼓捣我的Rime词库,自己坐的词库含了原神的相关,导致合并后的词库乱糟糟的,不能按拼音排序,可是恶心死我了,但是词库又太大,总不能为此搞个数据库吧……那又杀鸡牛刀了……所以四处寻找低成本的解决方案。

补充:词库大概35w词,1000w字左右

大家有啥好办法吗?

如题,参赛选手的要求如下:

至少能实现下列要求中的一个,至少支持GBK编码的所有汉字,仅支持GB2312的不予考虑

  1. 拼音排序
  2. 笔画排序
  3. 姓名笔画/姓氏笔画排序(区别见此
  4. 汉字转拼音/汉字转笔画

Java

  1. GitHub - Towdium/PinIn: Java library for Chinese text match using Pinyin - 用于各类汉语拼音匹配问题的 Java 库

Python

这应该是最简单的吧,安装完库就能跑,问题是资源开销太大,效率太低已被我放弃

  1. GitHub - mozillazg/python-pinyin: 汉字转拼音(pypinyin)

JS

  1. GitHub - theajack/cnchar: 🇨🇳 功能全面的汉字工具库 (拼音 笔画 偏旁 成语 语音 可视化等) (Chinese character util)
  2. GitHub - hotoo/pinyin: 🇨🇳 汉字拼音 ➜ hàn zì pīn yīn

Rust

  1. pinyin - Rust
  2. GitHub - Chaoses-Ib/IbPinyinLib: 一个高性能 Rust 拼音匹配库,支持 C、AHK2
  3. https://gitee.com/BuPin/rust_chinese_sort

Go

  1. GitHub - mozillazg/go-pinyin: 汉字转拼音

Cpp(C++)/C

  1. GitHub - Chaoses-Ib/IbPinyinLib: 一个高性能 Rust 拼音匹配库,支持 C、AHK2

C#

  1. GitHub - toolgood/ToolGood.Words.Pinyin: pinyin 拼音
  2. GitHub - hstarorg/TinyPinyin.Net: 适用于.Net平台的快速、低内存占用的汉字转拼音库。核心算法来自TinyPinyin(https://github.com/promeG/TinyPinyin)
  3. GitHub - zedseven/Romanization.NET: A library for romanization of widely-used languages using common romanization systems.
1 个赞

自己写着玩的排序,效率一般般,用本地环境的规则排序,支持多种语言,windows怎么排的他就怎么排,有个问题是00会在0前,01会在1前,懒得改了

import locale
import os
import re
from typing import Union


def sort_list(list_origin: list, order: str = 'ASC') -> Union[list, SystemExit]:
    """
    排序列表list
    :param list_origin: 原始的list
    :param order: 排序类型,'ASC'升序或'DESC'降序
    :return: 排序后的list
    """
    # 初始化本地环境
    locale.setlocale(locale.LC_ALL, '')

    # 转换list
    dict_convert = _convert_list_digit(list_origin)
    list_convert = dict_convert.keys()

    # 使用sorted函数对转换后的list进行排序
    list_convert_sorted = sorted(list_convert, key=locale.strxfrm)

    # 还原原始list
    list_sorted = []
    for item in list_convert_sorted:
        value_list = dict_convert[item]
        value_list = sorted(value_list)
        list_sorted += value_list

    # 按升降序参数返回对应list
    if order.upper() == 'ASC':
        return list_sorted
    elif order.upper() == 'DESC':
        return list_sorted[::-1]
    else:
        return SystemExit('传入参数错误,请检查!')


def sort_path(dirpath: str, order: str = 'ASC', filetype: str = 'both', depth: int = 0) -> list:
    """
    排序指定路径中的文件/文件夹
    :param dirpath: 文件夹路径
    :param order: 排序类型,'ASC'升序或'DESC'降序,默认为'ASC'
    :param filetype: 排序的文件类型,'file'文件或'folder'文件夹或'both'两者,默认为'both'
    :param depth: 遍历的层级深度,默认为0(最大层)
    :return: 根据参数返回不同的完整路径list
    """
    path_sorted = [dirpath]  # 存放最终结果
    current_listdir_sorted_folder = [dirpath]  # 当前层级中的文件夹
    current_listdir_sorted_folder_copy = current_listdir_sorted_folder.copy()  # 用于递归
    if depth == 0:
        depth = 100

    current_depth = 0
    while current_depth < depth and current_listdir_sorted_folder:
        current_depth += 1
        for path in current_listdir_sorted_folder_copy:
            current_listdir_sorted = _sort_path_listdir(path, order=order, filetype=filetype)
            current_index = path_sorted.index(path)
            path_sorted[current_index + 1:current_index + 1] = current_listdir_sorted  # 利用切片插入列表元素(不能用insert)
            current_listdir_sorted_folder.remove(path)
            current_listdir_sorted_folder += [i for i in current_listdir_sorted if os.path.isdir(i)]
        current_listdir_sorted_folder_copy = current_listdir_sorted_folder.copy()

    # 删除一开始赋值的多余的项目
    path_sorted.remove(dirpath)
    # 额外处理文件类型为file时的情况
    if filetype == 'file':
        path_sorted = [i for i in path_sorted if os.path.isfile(i)]

    return path_sorted


def _sort_path_listdir(dirpath: str, order: str = 'ASC', filetype: str = 'both') -> Union[SystemExit, list]:
    """
    排序指定路径中的文件/文件夹(仅第1层下级目录),并返回完整路径list
    :param dirpath: 文件夹路径
    :param order: 排序类型,'ASC'升序或'DESC'降序
    :param filetype: 排序的文件类型,'file'文件或'folder'文件夹或'both'两者
    :return: 排序后的完整路径list
    """
    listdir = os.listdir(dirpath)
    listdir_fullpath = [os.path.normpath(os.path.join(dirpath, i)) for i in listdir]
    listdir_fullpath_folder = [i for i in listdir_fullpath if os.path.isdir(i)]
    listdir_fullpath_file = [i for i in listdir_fullpath if os.path.isfile(i)]

    list_sorted_fullpath_folder = sort_list(listdir_fullpath_folder, order=order)
    list_sorted_fullpath_file = sort_list(listdir_fullpath_file, order=order)

    if filetype.lower() in ['both', 'file']:  # 如果排序类型是file也要返回整个list,但之后要删除folder项
        return list_sorted_fullpath_folder + list_sorted_fullpath_file
    elif filetype.lower() == 'folder':
        return list_sorted_fullpath_folder
    else:
        return SystemExit('传入参数错误,请检查!')


def _convert_list_digit(list_origin: list) -> dict:
    """
    对传入的list进行处理,处理内部元素中的连续数字字符串
    :param list_origin: 原始的list
    :return: 转换后的dict,键为新元素,值为原始元素的list(用于处理01、001补0后重复的情况)
    """
    # 遍历内部元素,利用正则提取所有连续数字字符串,最后得到其中最长的数字字符串长度
    longest_number_length = 0  # 最长的连续数字字符串长度
    pattern = r'(\d+)'
    for item in list_origin:
        numbers = re.findall(pattern, item)  # 提取数字字符串
        for i in numbers:
            if len(i) > longest_number_length:
                longest_number_length = len(i)

    dict_convert = dict()  # 转换后的dict,键为新元素,值为原始元素的list(用于处理01、001补0后重复的情况)

    # 重新遍历内部元素,利用正则将数字字符串补0扩展长度
    for item in list_origin:
        item_split = re.split(pattern, item)  # 分离数字字符串
        item_convert = ''  # 转换后的item
        for i in item_split:
            if i.isdigit():
                item_convert += i.zfill(longest_number_length)  # 对数字补0
            else:
                item_convert += i
        if item_convert not in dict_convert:
            dict_convert[item_convert] = []
        dict_convert[item_convert].append(item)

    return dict_convert

1 个赞

我觉得用数据库挺好的啊,35w词,也不算很少了,docker拉个mysql,建个表,干就完事了

而且建个库,可以同时实现你的所有需求,拼音,笔画,排序,转换,你还可以加上比如笔画数,韵母表,声母表,搞呗

要是还嫌麻烦,就sqlite直接搞,安装都省了

C# .Net自带,例子: C#中汉字排序简单示例(拼音/笔划) - 跟着阿笨一起玩.NET - 博客园
看起来排序方式还不只有拼音和笔画,不过我没看明白,完整列表: [MS-LCID]: LCID Structure | Microsoft Learn (最下面)
姓名姓氏笔画看起来不能直接出结果,得自己处理一下