求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

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

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

相关文章

基于PowerWord的储能在主动配电网中的仿真研究

摘要 主动配电网是智能配电网技术发展的高级阶段&#xff0c;分布式储能是主动配电网的重要组成部分&#xff0c;分布式储能的应用对主动配电网的规划、运行、网络拓扑、故障处理和保护、可再生能源电源的协调优化等方面带来不容忽视的影响&#xff0c;针对这一现状&#xff0c…

Kafka JNDI 注入分析(CVE-2023-25194)

Apache Kafka Clients Jndi Injection 漏洞描述 Apache Kafka 是一个分布式数据流处理平台&#xff0c;可以实时发布、订阅、存储和处理数据流。Kafka Connect 是一种用于在 kafka 和其他系统之间可扩展、可靠的流式传输数据的工具。攻击者可以利用基于 SASL JAAS 配置和 SAS…

UNIAPP框架中使用BLE蓝牙连接

概述 蓝牙连接包括搜索蓝牙设备&#xff0c;选择蓝牙设备&#xff0c;监听设备特征值&#xff0c;发送命令&#xff0c;断开蓝牙连接5种基础方法。Uni-App BLE 文档地址搜索设备时 搜索蓝牙设备 function discoveryDevices(pushDevice){console.log(enter search ble blueto…

02-PostgreSQL的基本使用

一、数据库操作 ①: 登录到数据库 psql -U postgres -d postgres -h 127.0.0.1②:查看所有数据库 \l③: 创建数据库 # 创建一个名为 mydb 的数据库 create database mydb;④:切换数据库 # \c 数据库名 \c mydb⑤:删除数据库 # 删除前 先确保数据库没有被连接 drop databa…

Linux学习笔记之五(父子进程、孤儿进程、僵尸进程、守护进程)

Linux 1、进程1.1、进程的六种状态1.2、创建子进程1.3、添加子进程任务1.4、孤儿进程、僵尸进程、守护进程1.4.1、避免僵尸进程1.4.2、创建守护进程1.4.3、杀死守护进程 1.5、综合练习 1、进程 进程可以简单的理解为一个正在执行的程序&#xff0c;它是计算机系统中拥有资源和…

小红书母婴博主投放技巧是什么,怎么避免无用功

如今&#xff0c;随着互联网的发展&#xff0c;母婴博主和社交媒体成为了很多妈妈们&#xff0c;获取育儿知识和建立社交圈的重要途径。今天为大家分享下小红书母婴博主投放技巧是什么&#xff0c;怎么避免无用功&#xff01; 一、优质的母婴博主在哪里 我们都知道&#xff0c;…

数据中台之数据分析

效果界面 技术方案 Notebook集成 在您的数据平台上,创建一个能够与Jupyter Notebook通讯的服务。通过Jupyter Notebook的HTTP API与Notebook实例进行交互,执行代码、获取输出等。用户界面 在数据开发/数据分析的代码框右上方,添加一个机器人样式的图标,用户点击后可以调起…

verdi如何打开时可以加载配置比如字体

打开tcl使能 找到配置字体的命令 其实其他有需要的文件配置都可以在这里找到对应的指令 存储文件 新建verdi001.tcl文件 输入想要调整的字体以及大小 verdiSetFont -font "Bitstream Vera Sans" -size "18" verdiSetFont -monoFont "Courier&q…

CPU眼里的 class vs struct

转自微信公众号《阿布编程》 “我们能用C语言实现C的&#xff1a;继承、成员函数、虚函数吗&#xff1f;不仅可以&#xff0c;而且还一摸一样&#xff01;” 01 — 提出问题 说到C和C的差别&#xff0c;大家很容易联想到面向对象和面向过程的差异。毕竟类&#xff0c;也就是…

Java @NotBlank反射校验

在实际项目中&#xff0c;遇到了导入数据校验是否为空的情况&#xff0c;只使用Javax的NotBlank注解并没有什么用&#xff0c;还需要使用工具类校验&#xff0c;具体代码如下&#xff1a; pojo代码如下&#xff1a; import com.alibaba.excel.annotation.ExcelIgnore; import …

多篇论文介绍-摘要

论文地址https://arxiv.org/pdf/2301.10051.pdf 目录 01CIEFRNet&#xff1a;面向高速公路的抛洒物检测算法 02改进 YOLOv5 的 PDC 钻头复合片缺损识别 03 基于SimAM注意力机制的DCN-YOLOv5水下目标检测 04 基于改进YOLOv7-tiny 算法的输电线路螺栓缺销检测 ​编辑05 基于改进Y…

亚马逊鲲鹏系统能做什么

亚马逊鲲鹏系统是一款能绕过亚马逊智能检测&#xff0c;完全模拟人类真实行为&#xff0c;通过模拟真实的人流量来帮助你提升你的产品排名&#xff0c;让你的产品出现在搜索首页&#xff0c;从而快速提高你的销售业绩的营销工具&#xff01; 主要的功能有批量注册买家号、AI智能…

【原创学位论文】基于python和定向爬虫的商品比价系统.docx

基于python和定向爬虫的商品比价系统 Price Comparison System for Products Based on Python and Targeted Web Crawling 目录 目录 2 摘要 3 关键词 3 第一章 绪论 4 1.1 研究背景 4 1.2 研究意义 5 1.3 国内外研究现状 7 1.4 本文主要工作和章节安排 8 第二章 Python基础…

新生儿疝气:原因、科普和注意事项

引言&#xff1a; 新生儿疝气是一种在婴儿中相对较常见的状况&#xff0c;很多新父母可能对这一现象感到困惑和焦虑。疝气发生时&#xff0c;内腹腔的一部分可能穿过腹壁的弱点&#xff0c;导致腹部出现凸起。本文将科普新生儿疝气的原因&#xff0c;提供相关信息&#xff0c;…

计算机基础知识48

web应用程序 # Django框架是一款专门用来开发web应用的框架 # Web应用程序是一种可以通过浏览器访问的应用程序, B/S架构 案例&#xff1a;淘宝网、京东网... # 应用程序有两种模式: C/S&#xff1a;客户端/服务器端程序&#xff0c;这类程序一般独立运行 B/S&#xff1…

C++跨DLL内存所有权问题探幽(二)CRT中MT和MD混用导致的所有权问题

0xC0000374: 堆已损坏。 (参数: 0x00007FFA1E9787F0)。 _Mem 是 nullptr 我在开发的过程中有遇到上面两个东西的bug&#xff0c;百思不得其解&#xff0c;最后才发现这个和两个DLL中的MT和 MD选项有关系。 具体情境时&#xff1a;我在一个MT编译的DLL A中引用了一个MD编译的D…

数据结构与算法C语言版学习笔记(5)-串,匹配算法、KMP算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、串的定义二、串的存储结构1.顺序结构2.链式结构 三、串的朴素的模式匹配算法&#xff08;暴力匹配算法&#xff09;1.背景2.假设我们要从下面的主串 S"…

“最强”机器学习辅助!利用自然语言让机器人更好地理解开放性世界

原创 | 文 BFT机器人 想象一下&#xff0c;你正在国外拜访朋友&#xff0c;打开他的冰箱看看有没有能够制作一顿美味早餐的食材。最初&#xff0c;冰箱里的许多物品对你来说都很陌生&#xff0c;每个物品的包装都是你不熟悉的。你开始试图理解每个物品的用途&#xff0c;并根据…

重温设计模式之什么是设计模式?

设计面向对象软件比较困难&#xff0c;而设计可复用的面向对象软件就更加困难。你必须找到相关的对象&#xff0c;以适当的粒度将它们归类&#xff0c;再定义类的接口和继承层次&#xff0c;建立对象之间的基本关系。你的设计应该对手头的问题有针对性&#xff0c;同时对将来的…

万界星空科技MES系统软件体系架构及应用

MES系统是数字化车间的核心。MES通过数字化生产过程控制&#xff0c;借助自动化和智能化技术手段&#xff0c;实现车间制造控制智能化、生产过程透明化、制造装备数控化和生产信息集成化。生产管理MES系统主要包括车间管理系统、质量管理系统、资源管理系统及数据采集和分析系统…