【动态规划:最短编辑路径】的应用:excel diff功能

news2025/1/18 17:16:36
开篇说明

如果在这里获得过启发和思考,希望点赞支持!对于内容有不同的看法欢迎来信交流。
技术栈 >> java
邮箱 >> 15673219519@163.com

描述
  • 在游戏行业中通常使用excel做配表,修改配表是一个频繁的操作。在修改之后,为减少认为的误操作。为此我们需要指定两个版本的配表进行对比功能。
  • 本文excel diff不限于游戏行业,适用于任意两个excel直接的对比。
动态规划:最短编辑路径 介绍
  • 最短编辑路径,简单的说就是"字符串1"改成"字符串2"需要经过多少步;如字符串"ABC"改成"ADCE"需要如下步骤
    • 1,删除B
    • 2,新增D
    • 3,新增E
      通过以上步骤我们就可以实现:字符串"ABC"改成"ADCE"
  • 通过上面的我们可以知道,这些步骤就是两个字符串之间的不同。
  • 动态规划-最短编辑路径
实现思路
  • 通过上面介绍的字符串"ABC"改成"ADCE"案例,类比到excel就是每一行的删除/新增就可以重任意一个excel表格变成另一个excel表格。其中变化的每一步就是这两个excel的不同之处。
  • excel我们可以理解就是可以通过一个二维数组保存数据,这里我们做一个降维操作,把它变成一个一维数组。也就是每一行的数据当作一个元素处理。
实现效果

在这里插入图片描述

实现步骤
  • 第一步: 读取excel的数据,并且把每一行的数据当作一个元素,整个excel表格的数据可以直接存入一个List中。
  • 第二步:写一个方法传入两个List,返回差异List
    @Data
    @AllArgsConstructor
    public static class Row {
        // 格子信息
        private List<Cell> cells;
        // diff + - =
        private String diff;
        // 行号
        private Integer rowNum;
        // 旧行号
        private Integer oldRowNum;
    }
private static List<Row> compareLines(List<Row> lines1, List<Row> lines2) {

        List<Row> differences = new ArrayList<>();
        int[][] LCS = new int[lines1.size() + 1][lines2.size() + 1];

        // 计算LCS矩阵
        for (int i = 1; i <= lines1.size(); i++) {
            for (int j = 1; j <= lines2.size(); j++) {
                if (lines1.get(i - 1).equals(lines2.get(j - 1))) {
                    LCS[i][j] = LCS[i - 1][j - 1] + 1;
                } else {
                    LCS[i][j] = Math.max(LCS[i - 1][j], LCS[i][j - 1]);
                }
            }
        }

        // 从LCS矩阵中提取差异
        int i = lines1.size();
        int j = lines2.size();
        while (i > 0 || j > 0) {
            if (i > 0 && j > 0 && lines1.get(i - 1).equals(lines2.get(j - 1))) {
                Row row = lines2.get(j - 1);
                row.setDiff("=");
                row.setRowNum(j);
                row.setOldRowNum(i);
                differences.add(row);
                i--;
                j--;
            } else if (j > 0 && (i == 0 || LCS[i][j - 1] >= LCS[i - 1][j])) {// +
                Row row = lines2.get(j - 1);
                row.setDiff("+");
                row.setRowNum(j);
                differences.add(row);
                j--;
            } else { // -
                Row row = lines1.get(i - 1);
                row.setDiff("-");
                row.setRowNum(i);
                row.setOldRowNum(i);
                differences.add(row);
                i--;
            }
        }
        // 翻转差异列表
        List<Row> reversed = new ArrayList<>();
        for (int k = differences.size() - 1; k >= 0; k--) {
            reversed.add(differences.get(k));
        }
        return reversed;
    }
  • 第三步:compareLines返回的就是excel的diff结果。需要新增那些行,需要删除那些行。就可以由excel1编辑成excel2。
拓展
  • 目前上面的实现仅仅diff到行的维度,那么如何实现diff中每个格子的变化。这边需要分情况考虑…
  • 最终的两个excel的行数是否发生变化。
  • 如果excel1(10行),变化后的excel(20行),这种目前是没有我没有想到很好的处理到每个格子,只能diff到行。
  • 如果excel1(10行),变化后的excel(10行),可以根据行号相同的行数再次通过compareLines方法找出差异格子,注意这里传入的应该是格子的数据列表。

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

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

相关文章

Python next函数

在Python编程中&#xff0c;next()函数是一个非常重要且常用的内置函数&#xff0c;用于迭代器对象中获取下一个元素。迭代器是一种可以逐个访问数据元素的对象&#xff0c;例如列表、元组、字典等。本文将深入探讨Python中的next()函数&#xff0c;包括基本用法、迭代器协议、…

STM32中断定时器的使用

使用systimer来产生较为精确的定时&#xff0c;之前使用for循环来产生。 用示例工程时产生错误&#xff0c;原因是调用F103的3种容量器件&#xff0c;需要更换S汇编头函数。 另外在工程设置中&#xff0c;需要把HD设置为MD&#xff0c;重新编译即可成功。

UVa1359/LA3491 Hills

题目链接 本题是2005年ICPC亚洲区域赛杭州欧赛区的H题 题意 平面上有 n&#xff08;n≤500&#xff09;条线段&#xff0c;其中每条线段的端点都不会在其他线段上。你的任务是数一数有多少个“没有被其他线段切到”的三角形&#xff08;即小山&#xff09;。如下图所示&#x…

NS安装-CentOS服务器安装Nightscout CGM

NS CGM 安装必要条件 有自己的云服务器好像没有2&#xff0c;有云服务器就行了 安装顺序 先安装数据库&#xff0c;目前支持的是 MongoDB &#xff0c;官方推荐4&#xff0c;其实目前最新版本就行。可以用宝塔安装&#xff0c;比较简单克隆代码&#xff0c;我是放到 /opt/ns…

使用可靠的情报在危机中做出明智的决策

近年来&#xff0c;随着地缘政治威胁的增加&#xff0c;组织逐渐发现错误信息对危机时期做出关键决策的重大影响。国际 SOS 发现各种规模的企业都在努力分析危机期间 24/7 可用的大量信息&#xff0c;并使用可信来源及时提供决策信息&#xff0c;特别是为了员工的健康和安全&am…

PAM | 账户安全 | 管理

PAM PAM&#xff08;Pluggable Authentication Modules&#xff0c;可插入式身份验证模块&#xff09;是一个灵活的身份验证系统&#xff0c;允许我们通过配置和组合各种模块来实现不同的身份验证策略。 在 Linux 或类 Unix 系统中&#xff0c;常见的 PAM 模块包括以下几种类…

[深度学习] 深入理解什么是卷积神经网络

​ &#x1f308; 博客个人主页&#xff1a;Chris在Coding &#x1f3a5; 本文所属专栏&#xff1a;[深度学习] ❤️ 热门学习专栏&#xff1a;[Linux学习] ⏰ 我们仍在旅途 目录 1.卷积的定义 2.卷积的"卷"在哪里 3.什么又是卷积神…

PyCharm 自动添加文件头注释

PyCharm 自动添加文件头注释 1. File and Code Templates2. Python FileReferences 1. File and Code Templates File -> Settings -> Editor -> File and Code Templates -> Python Script Reformat according to style & Enable Live Templates Created by…

悦耳的现代简约风,还可定义个性听感,森海塞尔ACCENTUM无线耳机体验

在头戴式耳机领域&#xff0c;森海塞尔本身的硬件实力确实足够出色 &#xff0c; 到了蓝牙时代 &#xff0c; 也推出了一些很有质感的产品 &#xff0c; 最近我尝试了较新的一款 ACCENTUM 耳机 &#xff0c; 它属于森海塞尔一个全新的系列 &#xff0c; 耳机本身的侧重点也很明…

PyCharm 新建目录 (directory or folder)

PyCharm 新建目录 [directory or folder] 1. 新建目录2. Enter new directory name -> OKReferences 1. 新建目录 right mouse click on the project -> New -> Directory 2. Enter new directory name -> OK ​​​ References [1] Yongqiang Cheng, https:/…

图论之dfs与bfs的练习

dfs--深度优选搜索 bfs--广度优先搜索 迷宫问题--dfs 问题&#xff1a; 给定一个n*m的二维迷宫数组其中S是起点&#xff0c;T是终点&#xff0c;*是墙壁&#xff08;无法通过&#xff09;&#xff0c; .是道路 问从起点S出发沿着上下左右四个方向走&#xff0c;能否走到T点&a…

python如何模拟登录Github

首先进入github登录页&#xff1a;https://github.com/login 输入账号密码&#xff0c;打开开发者工具&#xff0c;在Network页勾选上Preserve Log&#xff08;显示持续日志&#xff09;&#xff0c;点击登录&#xff0c;查看Session请求&#xff0c;找到其请求的URL与Form Da…

Linux——网络通信TCP通信常用的接口和tcp服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符&#xff0c;他的作用就是打开一个网络通讯端口&#xff0c;返回的这个描述符其实就可以理解为一个文件描述符&a…

GPT升级信息:能记住用户的喜好和习惯!

OpenAI刚刚宣布了ChatGPT的一项激动人心的更新&#xff01; OpenAI在ChatGPT中新加了记忆功能和用户控制选项&#xff0c;这意味着GPT能够在与用户的互动中记住之前的对话内容&#xff0c;并利用这些信息在后续的交谈中提供更加相关和定制化的回答。 这一功能目前正处于测试阶段…

SpringMVC回顾总结笔记

MVC是一种思想而SpringMVC是具体的实现&#xff08;Ioc和DI的关系&#xff09; 在创建项目的时候勾选的SpringWeb框架就是SpringMVC框架 与浏览器建立连接 默认返回的是一个 view 视图。需要添加ResponseBody说明返回的是json数据。RestController是ControllerResponseBody…

【Java EE初阶十四】网络编程TCP/IP协议(一)

1. 网络编程 通过网络&#xff0c;让两个主机之间能够进行通信->就这样的通信来完成一定的功能&#xff0c;进行网络编程的时候&#xff0c;需要操作系统给咱们提供一组API&#xff0c;通过这些API来完成编程&#xff1b;API可以认为是应用层和传输层之间交互的路径&#xf…

Leetcode刷题笔记题解(C++):120. 三角形最小路径和

思路&#xff1a;动态规划&#xff0c;去生成一个对应的当前节点的最小路径值&#xff0c;对应的关系如下所示 dp[0][0] triangle[0][0] dp[i][0] triangle[i][0]dp[i-1][0] dp[i][i] triangle[i][i]dp[i-1][i] dp[i][j] triangle[i][j]min(dp[i-1][j-1],dp[i-1][j]) …

扫描电子显微镜(SEM)样品制备要求与方法解析

扫描电子显微镜&#xff08;Scanning Electron Microscope&#xff0c;简称SEM&#xff09;是一种强大的分析工具&#xff0c;广泛应用于材料科学、生物学、医学、半导体材料和化学化工等领域。SEM能够提供高分辨率的表面形貌图像&#xff0c;因此样品制备成为获取准确、清晰图…

在 MyBatis 中,可以使用相同的 SQL 映射语句进行批量删除和单个删除。

目录 前端代码&#xff1a; 后端代码&#xff1a; controller service层接口 service接口的实现 mapper层接口 xml sql 效果&#xff1a;&#xff08;点击操作列的删除&#xff0c;可删除一行数据。勾选多个多选框再点击批量删除&#xff0c;可删除多个&#xff09; …

Postman路径修改

默认安装好Postman之后&#xff0c;默认路径在&#xff1a;C:\Users\用户名\AppData\Local\Postman。 修改路径只需要将整个文件夹拷贝到需要移动的位置即可&#xff0c;然后重新创建一个快捷方式。再删除原来路径的文件夹。