NLP 开源形近字算法之相似字列表(番外篇)

news2024/11/25 20:33:17

在这里插入图片描述

需求

有时候我们并不是需要返回两个字的相似,而是需要返回一个汉字的相似列表。

实现思路

我们可以分别计算所有的汉字之间的相似度,然后保留最大的前100个,放在字典中。

然后实时查询这个字典即可。

实现方式

bihuashu_2w.txt 中我们主要需要的是对应的 2W 常见汉字。

hanzi_similar_list.txt 用来存放汉字和相似字的映射关系。

数据初始化

public static void main(String[] args) {
    final String path = "D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\hanzi_similar_list.txt";
    // 读取列表
    List<String> lines = FileUtil.readAllLines("D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\nlp\\bihuashu_2w.txt");
    // 所有的单词
    Set<String> allWordSet = new HashSet<>();
    for(String line : lines) {
        String word = line.split(" ")[0];
        allWordSet.add(word);
    }
    // 循环对比
    for(String word : allWordSet) {
        List<String> list = getSimilarListData(word, allWordSet);
        String line = word +" " + StringUtil.join(list, "");
        FileUtil.append(path, line);
    }
}
  • 优先级队列取前 100 个

我们通过优先级队列存储:

private static List<String> getSimilarListData(String word, Set<String> wordSet) {
    PriorityQueue<SimilarListDataItem> items = new PriorityQueue<>(new Comparator<SimilarListDataItem>() {
        @Override
        public int compare(SimilarListDataItem o1, SimilarListDataItem o2) {
            // 相似度大的放在前面
            return -o1.getRate().compareTo(o2.getRate());
        }
    });
    for(String other : wordSet) {
        if(word.equals(other)) {
            continue;
        }
        // 对比
        double rate = HanziSimilarHelper.similar(word.charAt(0), other.charAt(0));
        SimilarListDataItem item = new SimilarListDataItem(other, rate);
        items.add(item);
    }
    final int limit = 100;
    List<String> wordList = new ArrayList<>();
    for(SimilarListDataItem item : items) {
        wordList.add(item.getWord());
        if(wordList.size() >= limit) {
            break;
        }
    }
    return wordList;
}

相似字的获取

初始化好数据之后,一切就变得非常简单:

  • 接口定义
/**
 * 数据接口-相似列表
 * @author binbin.hou
 * @since 1.3.0
 */
public interface IHanziSimilarListData {

    /**
     * 返回数据信息
     * @param word 单词
     * @return 结果
     * @since 1.3.0
     */
    List<String> similarList(String word);

}
  • 数据获取
public class HanziSimilarListData implements IHanziSimilarListData {

    private static volatile Map<String, List<String>> map = Guavas.newHashMap();


    @Override
    public List<String> similarList(String word) {
        if(MapUtil.isEmpty(map)) {
            initDataMap();
        }

        return map.get(word);
    }

    private void initDataMap() {
        if(MapUtil.isNotEmpty(map)) {
            return;
        }

        //DLC
        synchronized (map) {
            if(MapUtil.isEmpty(map)) {
                List<String> lines = StreamUtil.readAllLines("/hanzi_similar_list.txt");

                for(String line : lines) {
                    String[] words = line.split(" ");
                    // 后面的100个相近词
                    List<String> list = StringUtil.toCharStringList(words[1]);
                    map.put(words[0], list);
                }
            }
        }
    }

}

便利性

为了用户使用方便,我们在 HanziSimilarHelper 中添加 2 个工具类方法:

/**
 * 相似的列表
 * @param hanziOne 汉字一
 * @param limit 大小
 * @return 结果
 * @since 1.3.0
 */
public static List<String> similarList(char hanziOne, int limit) {
    return HanziSimilarBs.newInstance().similarList(hanziOne, limit);
}
/**
 * 相似的列表
 * @param hanziOne 汉字一
 * @return 结果
 * @since 1.3.0
 */
public static List<String> similarList(char hanziOne) {
    return similarList(hanziOne, 10);
}

测试效果

我们使用看一下效果:

我们来看一下【爱】的形近字。

List<String> list = HanziSimilarHelper.similarList('爱');
Assert.assertEquals("[爰, 爯, 受, 爭, 妥, 憂, 李, 爳, 叐, 雙]", list.toString());

开源地址

为了便于大家使用学习,项目已开源。

GitHub - houbb/nlp-hanzi-similar: The hanzi similar tool.(汉字相似度计算工具,中文形近字算法。可用于手写汉字识别纠正,文本混淆等。)

小结

一个字的形近字可以做很多有趣的事情,这个要看大家的想象力。

实现方式也不难,最核心的还是相似度的计算。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BUG解决Button类不能从UnityEngine.UI中引用

Button does not contain a definition for onClick and no accessible extension method onClick accepting a first argument of type Button could be found (are you missing a using directive or an assembly reference?) 一个非常奇葩的问题;突然!!!!! using UnityEn…

什么是低代码开发平台(apaas)?低代码开发平台的价值有哪些

手码6500字&#xff0c;带你快速看懂&#xff1a;什么是低代码开发平台&#xff08;apaas&#xff09;&#xff0c;低代码有哪些价值&#xff0c;以及低代码平台的使用逻辑和心得。 一、什么是低代码开发平台&#xff08;apaas&#xff09;&#xff1f; 低代码开发平台是一种a…

【C++ 学习记录】(一)--你好,C++

写在前面 工作需要&#xff0c;重学C&#xff0c;实在是太痛苦了&#xff0c;大二的时候应试就没学会&#xff01;&#xff01; 进入正题 1.编程是怎么回事 C在百科上的解释是一种静态数据类型检查 的、支持多种编程范式&#xff08;面向过程与面向对象等&#xff09;的通用…

BTP Integration Suite学习笔记 - (Unit3) Developing with SAP Integration Suite

BTP Integration Suite学习笔记 - (Unit1) Developing with SAP Integration Suite BTP Integration Suite学习笔记 - (Unit2) Developing with SAP Integration Suite 带着一个问题去学&#xff1a;明明可以直接访问一个后端系统的OData服务&#xff0c;为什么还要再多绕一道C…

UE学习记录02----UMG创建控件模板+事件分发器

官网4.27&#xff1a; 创建控件模板 | 虚幻引擎文档 (unrealengine.com) 使用UMG创建的每个 控件蓝图 都被视为 用户控件&#xff0c;其可在其他控件蓝图中重复使用和放置。 其视觉效果和脚本功能都将延续到该蓝图中。 利用某些蓝图脚本&#xff0c;可创建UI控件的运行方式或…

echarts——环形图

const value_ze 60 const value2_ze 30 var myChart echarts.init(document.getElementById(myChart)); var option {title: {text: 目标完成率,subtext: [{a|${value_ze}}, {b|%}].join(),itemGap: 10,textStyle: {fontSize: 14,color: #fff,fontWeight: 500},subtextStyl…

springboot拦截器无法进行属性注入

文章目录 问题描述问题原因问题解决解决方法一解决方法二 总结 问题描述 今天在使用拦截器的时候遇见了一个奇怪的错误&#xff0c;就是在对拦截器进行属性注入的时候为null&#xff0c;具体如下 运行代码出现空指针异常 就是注入的Gson为null&#xff0c;这个问题很奇怪&a…

STM32 HAL库定时器输入捕获SlaveMode脉宽测量

STM32 HAL库定时器输入捕获SlaveMode脉宽测量 SlaveMode模式简介 ✨SlaveMode复位模式&#xff1a;在发生一个触发输入事件时&#xff0c;计数器和它的预分频器能够重新被初始化&#xff1b;同时&#xff0c;如果TIMx_CR1寄存器的URS位为低&#xff0c;还会产生一个更新事件UEV…

SQLSERVER中exec 与 exec sp_executesql 的用法及比较

SQLSERVER 提供 exec 与 exec sp_executesql &#xff08;2005版本开始&#xff09;执行动态sql。 一、EXEC 命令有两种用法 1、执行存储过程 exec 存储过程 参数 值 --或 exec 存储过程 值 exec 存储过程 存储过程中的参数参数{接受参数返回值} outputCREATE PROC…

空气净化器触摸屏中应用的电容式触摸芯片

现在人们对于居住环境要求较高&#xff0c;许多家庭会选用空气净化器吸咐污物。那么空气净化器原理是什么&#xff1f;空气净化器工作原理分为两种&#xff1a; 被动式空气净化器原理&#xff1a;是用风机将空气抽入机器&#xff0c;通过内部的滤网过滤空气&#xff0c;起到过滤…

亚马逊气候友好碳中和认证

CLIMATE PLEDGE FRIENDLY AND CARBON NEUTRAL Climate Pledge Friendly气候友好认证&#xff0c;亚马逊推出的气候友好认证是一种自愿性&#xff0c;倡导性的认证。那么这个Climate Pledge Friendly是个什么样的认证&#xff0c;如何才能获得这个气候友好认证标签呢&#xff1…

使用onnx和onnxruntime完成模型部署

模型部署定义 深度学习模型部署是指训练好的模型在特定环境中运行的过程。 模型部署的流水线如下&#xff1a; 使用任意一种深度学习框架来定义网络结构并训练模型训练好的模型的网络结构和参数会被转换成一种只描述网络结构的中间表示&#xff08;如&#xff0c;onnx、torch…

Shiro 初识

1&#xff0c;了解Shiro Shiro是一个安全框架&#xff0c;主要用于用户认证&#xff0c;访问授权&#xff0c;会话管理&#xff0c;数据加密 2&#xff0c;实践 2.1 创建文件 这个例子没有链接数据库&#xff0c; 所以需要在resources下创建文件shiro.ini shiro.ini内容&am…

Vant源码解析(三)van-stepper步进器

先说下自己的开发思路&#xff0c;然后在对照下vant组件的思路&#xff0c;来查找下自己的不足。 这个步进器有加和减的功能&#xff0c;还有输入的功能&#xff0c;限制最小和最大的功能。 我理解的Vant组件的思路 点击事件都是onTap,根据变量进行判断是加还是减&#xff0c;数…

vuecli5.x 配置图片输出为base64

解释&#xff1a;webpack的默认配置是小于一定的文件大小就要将图片转为base64, 所以尽量将这个阈值调大你的图片就可以转为base64; 当然这种做法不好, 会导致代码文件变大, 不过为了满足需求也没得办法。这年头大家都用 vite 了, 网上没有 vuecli5.x 这方面的记录, 写篇文章记…

腾讯内推 | 互联网大厂内推

分享 WLB、大厂内推&#xff0c;面经、热点新闻&#xff0c;可内推公司90&#xff0c;累计帮助6000 靠谱的内推君 专注于WLB、大厂精选内推&#xff0c;助力每位粉丝拿到满意的Offer&#xff01; 公司简述 腾讯以技术丰富互联网用户的生活。通过通信及社交平台微信和 QQ 促…

单模光模块和多模光模块有何区别,如何选择?

随着数据中心和5G应用的高速发展&#xff0c;光模块渐渐被越来越多的人所熟知&#xff0c;也得到了广泛应用。我们都知道&#xff0c;光模块可以根据参数类型来区分&#xff0c;如我们经常提到的单模光模块和多模光模块。那你知道单模光模块和多模光模块中的单模和多模分别代表…

基于物联网、移动互联网、一物一码等技术开发的质量溯源系统源码

什么是溯源系统? 溯源系统是物联网、移动互联网、一物一码等技术的整合应用。在产品生产过程中在重要环节可采集产品数据信息并形成产品溯源档案。从而形成产品从原料、生产加工、质量检测、物流运输等环节的信息监控。 溯源系统技术架构 技术架构&#xff1a;spring bootmy…

服务器数据库的防护策略与360后缀勒索病毒解密方法

在当今数字化时代&#xff0c;服务器数据安全面临着越来越多的挑战。其中&#xff0c;勒索病毒攻击就是一种常见的网络威胁之一&#xff0c;最近&#xff0c;很多的公司服务器数据库遭到了360后缀勒索病毒攻击&#xff0c;导致许多重要数据无法读取&#xff0c;一旦企业的数据库…

vue3和tauri直接下载Binary 数组的二进制文件内容到本地

通过发送url请求&#xff0c;直接获取到一个文件的Binary 数组内容&#xff0c;然后通过tauri的api&#xff1a;writeBinaryFile保存文件到本地电脑。 发送请求的时候&#xff0c;要加上响应类型&#xff1a;responseType: ResponseType.Binary 然后等返回的响应内容&#xf…