求2个字符串的最短编辑距离 java 实现
EditStepInfo.java:
import lombok.Getter;
import lombok.Setter;import java.io.Serializable;
import java.util.List;@Getter
@Setter
public class EditStepInfo implements Serializable {private String str1;private String str2;// str1和 str2 的最短编辑路基private int sed;private List<StepVO> steps;}
StepVO.java:
import lombok.Getter;
import lombok.Setter;import java.io.Serializable;@Getter
@Setter
public class StepVO implements Serializable {/*** 当前变换描述*/private String desc;private Character optChar1;private Character optChar2;/*** 当前变换成的字符串*/private String tempString;}
ShortestEditDistanceTest.java:
import java.util.ArrayList;
import java.util.List;public class ShortestEditDistanceTest {private static EditStepInfo[][] MAT_SED = null;public static void main(String[] args) {// m o t h e r// m o n s t e rString string1 = "mother";String string2 = "monster";MAT_SED = new EditStepInfo[ string1.length() ][ string2.length() ];EditStepInfo editStepInfo = calculateShortestEditDistance(string1, string2);System.out.println( string1 );System.out.println( string2 );System.out.println( "最小编辑距离:" + editStepInfo.getSed() );System.out.println( "编辑步骤:" );List<String> steps = editStepInfo.getSteps();for( String step:steps ){System.out.println( step );}}private static EditStepInfo calculateShortestEditDistance( String string1,String string2 ){if( string1 == null || string1.length() == 0 ){EditStepInfo editStepInfo = new EditStepInfo();editStepInfo.setStr1( string1 );editStepInfo.setStr2( string2 );editStepInfo.setSed( string2.length() );return editStepInfo;}if( string2 == null || string2.length() == 0){EditStepInfo editStepInfo = new EditStepInfo();editStepInfo.setStr1( string1 );editStepInfo.setStr2( string2 );editStepInfo.setSed( string1.length() );return editStepInfo;}int len1 = string1.length();int len2 = string2.length();for( int i=0;i<len1;i++ ){String str1 = string1.substring(0, i + 1);for( int j=0;j<len2;j++ ){String str2 = string2.substring(0, j + 1);EditStepInfo editStepInfo = new EditStepInfo();editStepInfo.setStr1( str1 );editStepInfo.setStr2( str2 );if( str1.length() == 1 ){if( str2.length() == 1 ){if( str1.equals( str2 ) ){// str1 和 str2 的长度均为1,并且 str1 和 str2 相等// a// aeditStepInfo.setSed( 0 );}else {// str1 和 str2 的长度均为1,并且 str1 和 str2 不相等// a// bList<StepVO> steps = new ArrayList<>();StepVO step = new StepVO();step.setDesc( "将 " + str1 + " 修改为 " + str2 );step.setTempString( str2 );steps.add( step );editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}}else {if( str2.contains( str1 ) ){// str1 的长度为1,str2 的长度大于1,并且 str1 在 str2 中不出现// a// ..a...// 组装编辑步骤信息List<StepVO> steps = buildEditSteps( str1.charAt(0),str2 );editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}else {// str1 的长度为1,str2的长度大于1,并且str1在 str2中不存在// a// ..b...// 组装编辑步骤信息List<StepVO> steps = buildEditSteps(str1.charAt(0), str2);editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}}}else {if( str2.length() == 1 ){if( str1.contains( str2 ) ){// ...a..// a// 组装编辑步骤信息List<String> steps = buildEditSteps(str1, str2.charAt(0));editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}else {// ...b..// a// 组装编辑步骤信息List<String> steps = buildEditSteps(str1, str2.charAt(0));editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}}else {Character lastChar1 = getLastChar(str1);Character lastChar2 = getLastChar(str2);if( lastChar1.equals( lastChar2 ) ){// ------a// ---------a// 组装编辑步骤信息EditStepInfo editStepInfo_prev = MAT_SED[i - 1][j - 1];List<String> steps = new ArrayList<>();List<String> steps_prev = editStepInfo_prev.getSteps();if( steps_prev != null ){steps.addAll( steps_prev );}editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}else {// -----a// ........b// 1. str1 的 "-----" 部分转换为 str2,再删除 a// 2. str1 转换为 str2 的 "........" 部分,再添加 b// 3. str1 的 "-----" 部分转换为 str2 的 "........" 部分,再将a修改为 b// 求 方法1、2、3中选一个最小的编辑步骤作为最终的编辑步骤EditStepInfo editStepInfo_prev_1 = MAT_SED[i - 1][j];EditStepInfo editStepInfo_prev_2 = MAT_SED[i][j - 1];EditStepInfo editStepInfo_prev_3 = MAT_SED[i - 1][j - 1];EditStepInfo editStepInfo_prev_min = editStepInfo_prev_1;int minMethodNum = 1;if( editStepInfo_prev_2.getSed() < editStepInfo_prev_min.getSed() ){editStepInfo_prev_min = editStepInfo_prev_2;minMethodNum = 2;}if( editStepInfo_prev_3.getSed() < editStepInfo_prev_min.getSed() ){editStepInfo_prev_min = editStepInfo_prev_3;minMethodNum = 3;}List<String> steps = new ArrayList<>();List<String> steps_prev_min = editStepInfo_prev_min.getSteps();if( steps_prev_min != null ){steps.addAll( steps_prev_min );}if( minMethodNum == 1 ){steps.add( "删除 " + lastChar1 );}else if( minMethodNum == 2 ){steps.add( "添加 " + lastChar2 );}else if( minMethodNum == 3 ){steps.add( "修改 " + lastChar1 + " 为 " + lastChar2 );}editStepInfo.setSteps( steps );editStepInfo.setSed( steps.size() );}}}MAT_SED[ i ][ j ] = editStepInfo;}}return MAT_SED[ string1.length() - 1 ][ string2.length() - 1 ];}/*** 组装将字符 srcChar 转换成字符串 targetString 的编辑步骤* @param srcChar 例如:a* @param targetString 例如:bcdefg* @return*/private static List<StepVO> buildEditSteps(Character srcChar, String targetString) {boolean hasMeet = false;int length = targetString.length();List<StepVO> steps = new ArrayList<>();for( int i = 0;i < length;i++ ){Character char2 = targetString.charAt( i );if( hasMeet ){StepVO step = new StepVO();step.setDesc( "添加 " + char2 );step.setOptChar1( char2 );steps.add( step );}else {if( srcChar.equals( char2 ) ){// do nothinghasMeet = true;}else {StepVO step = new StepVO();step.setDesc( "添加 " + char2 );step.setOptChar1( char2 );steps.add( step );}}}if( !hasMeet ){// 此种情况只发生在 targetString 中不包含 srcChar 时StepVO step = new StepVO();step.setDesc( "删除 " + srcChar );step.setOptChar1( srcChar );steps.add( 0,step );}// 设置 每个步骤生成的 tempStringString tempString = String.valueOf( srcChar );for( StepVO step:steps ){String desc = step.getDesc();if( desc.startsWith( "删除" ) ){tempString = "";}else if( desc.startsWith( "添加" ) ){tempString += step.getOptChar1();}step.setTempString( tempString );}return steps;}private static List<StepVO> buildEditSteps(String srcString, Character targetChar) {// abcdefg// cboolean hasMeet = false;int length = srcString.length();List<StepVO> steps = new ArrayList<>();for( int i = 0;i < length;i++ ){Character char1 = srcString.charAt( i );if( hasMeet ){StepVO step = new StepVO();step.setDesc( "删除 " + char1 );step.setOptChar1( char1 );steps.add( step );}else {if( targetChar.equals( char1 ) ){// do nothinghasMeet =true;}else {StepVO step = new StepVO();step.setDesc( "删除 " + char1 );step.setOptChar1( char1 );steps.add( step );}}}if( !hasMeet ){StepVO step = new StepVO();step.setDesc( "添加 " + targetChar );step.setOptChar1( targetChar );steps.add( 0,step );}// todo 生成 tempStringString tempString = srcString;for( StepVO step:steps ){String desc = step.getDesc();if( desc.startsWith( "添加" ) ){}else if( desc.startsWith( "删除" ) ){}step.setTempString( null );}return steps;}private static Character getLastChar(String str) {if( str == null || str.length() == 0 ){return null;}return str.charAt(str.length() - 1);}
}
mother
monster
最小编辑距离:3
编辑步骤:
添加 n
添加 s
删除 h
相关文章:
求2个字符串的最短编辑距离 java 实现
EditStepInfo.java: import lombok.Getter; import lombok.Setter;import java.io.Serializable; import java.util.List;Getter Setter public class EditStepInfo implements Serializable {private String str1;private String str2;// str1和 str2 的最短编辑路…...

单例模式 rust和java的实现
文章目录 单例模式介绍应用实例:优点使用场景 架构图JAVA 实现单例模式的几种实现方式 rust实现 rust代码仓库 单例模式 单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建…...

tqdm学习
from tqdm import tqdmepochs 10 epoch_bar tqdm(range(epochs)) count 0 for _ in epoch_bar:count count1print("count {}".format(count))print(_)每次就是一个epoch...

Zigbee—网络层地址分配机制
🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:孤雏 0:21━━━━━━️💟──────── 4:14 🔄 ◀️ ⏸ ▶️ ☰ 💗关注…...

[Matlab]基于LSTM+NSGA2的风光火力发电策略优化
最近比较忙,好久没分享案例啦,今天简单分享一个滚动时域的多目标优化 一 模型介绍 1 风电 2 光伏 3 火电 4 储能 5 用电需求 等五个对象。 其中风电和光伏还有用电需求,用历史数据LSTM网络,训练一个预测模型;火电根据策…...

智安网络|探索人机交互的未来:自然语言处理的前沿技术
自然语言处理是人工智能领域中研究人类语言和计算机之间交互的一门学科。它涉及了语言的理解、生成、翻译、分类和摘要等多个方面。随着人们对自然语言处理的重视和需求不断增长,成为了热门的研究方向。 首先,我们需要了解自然语言处理的基本概念。自然…...

Could not load library libcudnn_cnn_train.so.8, 解决类似问题的思路与方法
完整报错 Could not load library libcudnn_cnn_train.so.8. Error: /home/ai/anaconda3/envs/ai/bin/../lib/libcudnn_ops_train.so.8: undefined symbol: _ZN5cudnn3ops26JoinInternalPriorityStreamEP12cudnnContexti, version libcudnn_ops_infer.so.8 错误原因 该错误其…...
孙子兵法_00000
第一篇:始计篇 孙子曰:兵者,国之大事,死生之地,存亡之道,不可不察也。 故经之以五事,校之以计,而索其情:一曰道,二曰天,三曰地,四曰将…...

代挂单页网址发布页+加盟代理+APP下载页源码
代挂单页加盟代理网址发布页app下载页HTML单页版本,自行修改源码内文字。自行修改联系方式、登录地址!上传即可使用。源码我已全部打包好,直接上传本站提供的源码,无后台,直接访问即可! 源码下载ÿ…...

计算机视觉驾驶行为识别应用简述
一、什么是计算机视觉识别? 计算机视觉识别是一种基于图像处理和机器学习的人工智能应用技术,可以用于多个场景。常见应用场景包括人脸识别、场景识别、OCR识别以及商品识别等。今天以咱们国产系统豌豆云为例,为大家梳理一下在车辆驾驶行为中…...
asp.net core configuration配置读取
asp.net core 默认注入了configuration配置服务,configuration可以从命令行、环境变量、配置文件读取配置。 这边主要演示从appsettings.json文件读取配置 1.读取单节点配置 { "name":"pxp" }//在控制器注入Iconfigurationprivate IConfigurat…...

windows上 Nexus 批量上传 maven依赖npm依赖
windows上 Nexus 批量上传 maven依赖/npm依赖 前言:windows系统上要有git环境,不然sh文件执行不了 1.批量上传maven依赖 设置脚本,把脚本放在依赖包的根目录执行,脚本名为upload.sh #!/bin/bash# 定义变量 while getopts &quo…...

已解决:Python Error: IndentationError: expected an indented block 问题
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂🦖…...

汽车标定技术(六)--基于模型开发如何生成完整的A2L文件(2)
目录 1. 自定义ASAP2文件 2. asap2userlib.tlc需要修改的部分 3. 标定量观测量地址替换 3.1 由elf文件替换 3.2 由map文件替换 3.3 正则表达式(含asap2post.m修改方法) 4.小结 书接上文汽车标定技术(五)--基于模型开发如何生成完整的A2L文件(1)-C…...
普华永道于进博会发布全新升级的DSAI投资管理数字化平台
上海,2023年11月9日——今日,在第六届中国国际进口博览会上,全球领先的专业服务机构普华永道推出了全新升级的创新投资管理产品:DSAI投资管理数字化平台。升级后的DSAI投资管理数字化平台具有收益分配自动计算和智能BI看板功能。作…...

ssm+vue的高校学生课堂考勤系统设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。
演示视频: ssmvue的高校学生课堂考勤系统设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转…...
常用hivesql记录
前言 hivesql中很多常用的功能,过段时间没有使用就容易忘记,需要去网上搜索,这里总结一下,省的以后还去去搜,供自己以后参考。 查看分区的行 show rowcount extended table_name;创建二级分区表 set hive.default.…...

C# OpenCvSharp 去除文字中的线条
效果 中间过程效果 项目 代码 using OpenCvSharp; using System; using System.Drawing; using System.Windows.Forms; using static System.Net.Mime.MediaTypeNames;namespace OpenCvSharp_Demo {public partial class frmMain : Form{public frmMain(){InitializeComponent…...

【树的存储结构,孩子链表】
文章目录 树和森林树的存储结构孩子链表 树和森林 森林:是m(m>0)棵互不相交的树的集合。 树的存储结构 1.双亲表示法 实现:定义结构数组存放树的结点,每个结点含两个域。 数据域:存放结点本身信息。 双亲域:指…...

到蒙古包了,这边天气-9度 很冷
【点我-这里送书】 本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...