求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 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
