手动实现 git 的 git diff 功能

这是 git diff 后的效果,感觉挺简单的,不就是 比较新旧版本,新增了就用 "+" 显示新加一行,删除了就用 "-" 显示删除一行,修改了一行就用 "-"、"+" 显示将旧版本中的该行干掉了并且新版本中增加了一行,即使用 "删除" + "新增" 操作代替 "修改" 操作,然后就用

然后我们写的测试代码如下:



import com.goldwind.ipark.common.util.MyStringUitls;
import org.apache.commons.text.similarity.LevenshteinDistance;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;



public class MyDiffTest {

    public static void main(String[] args) {
        List<String> lines_old = loadTxtFile2List("C:\\E\\javaCode\\git\\outer_project\\guodiantou\\gdtipark-user-servie\\src\\main\\java\\com\\goldwind\\ipark\\base\\test\\DemoClass1.java" );
        List<String> lines_new = loadTxtFile2List("C:\\E\\javaCode\\git\\outer_project\\guodiantou\\gdtipark-user-servie\\src\\main\\java\\com\\goldwind\\ipark\\base\\test\\DemoClass2.java");
        // lines1的起始行和 lines2 的起始行做映射

        // 扫描旧版本中的每一行
        int size = lines_old.size();
        for( int i=0;i<size;i++ ){
            // 从新版本中找该行
            String line_old = lines_old.get(i);
            String line_new = lines_new.get(i);

            // 如果发现版本中中该行的数据变了,那么提示删除了旧的行,添加了新的行
            if( line_new.equals( line_old ) ){
                System.out.println( line_old );
            }else {
                System.out.println( "- " + line_old );
                System.out.println( "+ " + line_new );
            }
        }
        // xxxx        xxxx1          -xxxx
        // yyyy        yyyy           +xxxx1
        // xxxxxx      xxxxxx         xxxxxx
        // zzzz        zzzz           zzzz

    }

    private static List<String> loadTxtFile2List(String filePath) {
        BufferedReader reader = null;
        List<String> lines = new ArrayList<>();
        try {
            reader = new BufferedReader(new FileReader(filePath));
            String line = reader.readLine();
            while (line != null) {
                // System.out.println(line);
                lines.add( line );
                line = reader.readLine();
            }
            return lines;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

其中用到的2个新旧版本的文本如下:

DemoClass1.java:


import com.goldwind.ipark.common.exception.BusinessLogicException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.similarity.LevenshteinDistance;

@Slf4j
public class DemoClass1 {

    private static final LevenshteinDistance LEVENSHTEIN_DISTANCE = LevenshteinDistance.getDefaultInstance();

    public static String null2emptyWithTrim( String str ){
        if( str == null ){
            str = "";
        }
        str = str.trim();
        return str;
    }

    public static String requiredStringParamCheck(String param, String paramRemark) {
        param = null2emptyWithTrim( param );
        if( param.length() == 0 ){
            String msg = "操作失败,请求参数 \"" + paramRemark + "\" 为空";
            log.error( msg );
            throw new BusinessLogicException( msg );
        }
        return param;
    }

    public static double calculateSimilarity( String str1,String str2 ){
        int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
        double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
        System.out.println("相似度:" + similarity);
        return similarity;
    }
}

DemoClass2.java:


import com.goldwind.ipark.common.exception.BusinessLogicException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.similarity.LevenshteinDistance;

@Slf4j
public class DemoClass2 {

    private static final LevenshteinDistance LEVENSHTEIN_DISTANCE = LevenshteinDistance.getDefaultInstance();
    private static final LevenshteinDistance LEVENSHTEIN_DISTANCE1 = LevenshteinDistance.getDefaultInstance();
    private static final LevenshteinDistance LEVENSHTEIN_DISTANCE2 = LevenshteinDistance.getDefaultInstance();

    public static String null2emptyWithTrim( String str ){
        if( str == null ){
            str = "";
        }
        str = str.trim();
        return str;
    }

    public static String requiredStringParamCheck(String param, String paramRemark) {
        param = null2emptyWithTrim( param );
        if( param.length() == 0 ){
            String msg = "操作失败,请求参数 \"" + paramRemark + "\" 为空";
            log.error( msg );
            throw new BusinessLogicException( msg );
        }
        return param;
    }

    public static double calculateSimilarity( String str1,String str2 ){
        int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
        double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
        System.out.println("相似度:" + similarity);
        return similarity;
    }
}
DemoClass2.java 相较于 DemoClass1.java 的区别是 "public class" 后面的类名不同,"private static final LevenshteinDistance LEVENSHTEIN_DISTANC..." 多复制了2行并改了名称,然后运行后显示差别如下:
import com.goldwind.ipark.common.exception.BusinessLogicException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.similarity.LevenshteinDistance;

@Slf4j
- public class DemoClass1 {
+ public class DemoClass2 {

    private static final LevenshteinDistance LEVENSHTEIN_DISTANCE = LevenshteinDistance.getDefaultInstance();
- 
+     private static final LevenshteinDistance LEVENSHTEIN_DISTANCE1 = LevenshteinDistance.getDefaultInstance();
-     public static String null2emptyWithTrim( String str ){
+     private static final LevenshteinDistance LEVENSHTEIN_DISTANCE2 = LevenshteinDistance.getDefaultInstance();
-         if( str == null ){
+ 
-             str = "";
+     public static String null2emptyWithTrim( String str ){
-         }
+         if( str == null ){
-         str = str.trim();
+             str = "";
-         return str;
+         }
-     }
+         str = str.trim();
- 
+         return str;
-     public static String requiredStringParamCheck(String param, String paramRemark) {
+     }
-         param = null2emptyWithTrim( param );
+ 
-         if( param.length() == 0 ){
+     public static String requiredStringParamCheck(String param, String paramRemark) {
-             String msg = "操作失败,请求参数 \"" + paramRemark + "\" 为空";
+         param = null2emptyWithTrim( param );
-             log.error( msg );
+         if( param.length() == 0 ){
-             throw new BusinessLogicException( msg );
+             String msg = "操作失败,请求参数 \"" + paramRemark + "\" 为空";
-         }
+             log.error( msg );
-         return param;
+             throw new BusinessLogicException( msg );
-     }
+         }
- 
+         return param;
-     public static double calculateSimilarity( String str1,String str2 ){
+     }
-         int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
+ 
-         double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
+     public static double calculateSimilarity( String str1,String str2 ){
-         System.out.println("相似度:" + similarity);
+         int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
-         return similarity;
+         double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
-     }
+         System.out.println("相似度:" + similarity);
- }
+         return similarity;

为啥???

如上两张图片,旧版本的第10行和新版本的第10行对应,从直观上看新版本的第11、12行是在旧版本的第10行和第11行之间插进去的,但是程序并不这么认为,它会认为将旧版本的第11行的空白行修改为了新版本的 “private static final LevenshteinDistance LEVENSHTEIN_DISTANCE1 = LevenshteinDistance.getDefaultInstance();” 为什么我们人眼会这么直观的感觉到 新版本的 第11、12行时插进去的,因为我们比较了新旧版本的第7、8、9、10行都差不多,旧版本的11~27行和新版本的 13~29行都差不多,所以自然而然的认为新版本的11、12行是直接插进去的,那么现在我们就来算法实现吧!

todo

todo

todo

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线上PDF文件展示

场景&#xff1a; 请求到的PDF&#xff08;url链接&#xff09;&#xff0c;将其展示在页面上 插件&#xff1a; pdfobject &#xff08;我使用的版本&#xff1a; "pdfobject": "^2.2.12" &#xff09; 下载插件就不多说了&#xff0c;下面将其引入&a…

线上ES集群参数配置引起的业务异常案例分析

本文介绍了一次排查Elasticsearch node_concurrent_recoveries 引发的性能问题的过程。 一、故障描述 1.1 故障现象 1. 业务反馈 业务部分读请求抛出请求超时的错误。 2. 故障定位信息获取 故障开始时间 19:30左右开始 故障抛出异常日志 错误日志抛出timeout错误。 故障之前…

大数据 DataX-Web 详细安装教程

目录 一、DataX-Web 介绍 1.1 DataX-Web 是什么 1.2 DataX-Web 架构 二、DataX-Web 安装部署 2.1 环境要求 2.2 安装 2.3 部署 2.4 数据库初始化 2.5 配置 2.6 启动服务 2.6.1 一键启动所有服务 2.6.2 一键取消所有服务 2.7 查看服务&#xff08;注意&#xff01…

2024深圳电子展,加快粤港澳电子信息发展,重点打造“湾区经济”

在“十四五”期间&#xff0c;中国电子信息产业面临着新形势和新特点。随着国家对5G、人工智能、工业互联网、物联网等“新基建”的加速推进&#xff0c;以及形成“双循环”新格局的形势&#xff0c;新型显示、集成电路等产业正在加速向国内转移。这一过程不仅带来了新的应用前…

HTTP协议抓包工具Charles 抓包图文完整教程

Charles是在您自己的计算机上运行的Web代理&#xff08;HTTP代理 / HTTP监视器&#xff09;&#xff0c;您的网络浏览器&#xff08;或任何其他Internet应用程序&#xff09;配置为通过Charles访问Internet&#xff0c;Charles可以为您记录并显示发送和接收的所有数据。 Http抓…

盘点43个Python登录第三方源码Python爱好者不容错过

盘点43个Python登录第三方源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 项目名称 bnuz中国电信校园网模拟登录&#xff0c;python selenium BNUZ教务系统认证爬虫Python语言实现&#xff0c;你可以用…

UNETR++:深入研究高效和准确的3D医学图像分割

论文&#xff1a;https://arxiv.org/abs/2212.04497 代码&#xff1a;GitHub - Amshaker/unetr_plus_plus: UNETR: Delving into Efficient and Accurate 3D Medical Image Segmentation 机构&#xff1a;Mohamed Bin Zayed University of Artificial Intelligence1, Univers…

工业级5G路由器:稳定性更高,网络速度更快!

随着5G技术的发展&#xff0c;5G路由器也越来越受到人们的关注。特别是工业级5G路由器&#xff0c;它的应用范围更广&#xff0c;稳定性更高&#xff0c;网络速度更快&#xff0c;已成为许多企业和工业领域的必备选择。 一、工业级5G路由器的特点 工业级5G路由器具有很多独特的…

社区物联网云服务架构设计

文章目录 1 摘要2 架构图2.1 社区物联网云服务网络拓扑图2.2 社区物联网云服务通讯流程图2.3 社区远程开锁功能流程图 3 应用场景 1 摘要 随着社区管理越来越智能化&#xff0c;社区物联网升级与改造的市场空间也越来越大。社区物联网包含楼宇对讲、门禁门锁、通道闸等等设备系…

Vue3(setup)中使用vue-cropper图片上传裁剪插件,复制代码直接使用

最近在项目中用到上传裁剪&#xff0c;看了一下代码&#xff0c;觉得这插件可可以。梳理了一下代码分享给大家 前端UI组件element-plus 如果你也用到了 &#xff0c;快速帮你解决了问题,别忘记点赞收藏 1.首先看效果图 因为版本vue-cropper 众多 &#xff0c;虽然网上有各…

S71200通过PROFINET协议和岛电数字控制器通讯

项目要求 西门子S71200PLC需要通过PROFINET协议和岛电数字控制器&#xff08;型号&#xff1a;SRS13A&#xff09;通讯&#xff0c;读取温度的测量值PV和设定值SV。 项目实施 采用NET90-PN-MBT&#xff08;以下简称“网关”&#xff09;&#xff0c;它是一款将Modbus TCP/RT…

用户隐私与游戏体验如何平衡?第二周 Web3 开发者集结精华回顾

由 TinTinLand 联合 Dataverse 、Web3Go 、Subquery 、Cregis 、Litentry、Aspecta、SpaceID、ANOME、VARA&Gear、Moonbeam、Mantle、Obelisk 等 10 余家 Web3 项目共同举办的 Web3 开发者赢积分活动已举办至第三周。精彩线上主题活动分享、近距离交流体验互动&#xff0c;…

京东采销面对面,洞悉行业新趋势 京东3C数码生态大会在武汉圆满举行

为促进湖北省3C数码产业发展&#xff0c;本地企业降本增效、促进行业交流、充分发挥京东集团全链路生态服务能力&#xff0c;支持地方3C特色产业提质增量。2023年11月23日&#xff0c;由京东零售、京东物流主办&#xff0c;湖北省电子商务行业协会联合协办的“聚力共赢、携手共…

想问问各位大佬,网络安全这个专业普通人学习会有前景吗?

网络安全是一个非常广泛的领域&#xff0c;涉及到许多不同的岗位。这些岗位包括安全服务、安全运维、渗透测试、web安全、安全开发和安全售前等。每个岗位都有自己的要求和特点&#xff0c;您可以根据自己的兴趣和能力来选择最适合您的岗位。 渗透测试/Web安全工程师主要负责模…

山西电力市场日前价格预测【2023-11-25】

1.日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-25&#xff09;山西电力市场全天平均日前电价为312.19元/MWh。其中&#xff0c;最高日前电价为350.80元/MWh&#xff0c;预计出现在09:15。最低日前电价为273.49元/MWh&#xff0c;预…

NX二次开发UF_CSYS_map_point 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_map_point Defined in: uf_csys.h int UF_CSYS_map_point(int input_csys, double input_point [ 3 ] , int output_csys, double output_point [ 3 ] ) overview 概述 Ma…

2.19 keil里面工具EventCorder使用方法

设置方法如下&#xff1a; 添加初始化代码如下&#xff1a; eventRecord.c #include "eventRecord.h" #include "usart.h" extern UART_HandleTypeDef *pcControlUart;/* RecordEvent初始化 */ void InitEventRecorder(void) {#ifdef RTE_Compiler_Even…

Elasticsearch知识

目录 Elasticsearch逻辑设计和物理设计 逻辑设计物理设计Elasticsearch原理 倒排索引文档的分析过程保存文档搜索文档写数据的底层原理 数据刷新&#xff08;fresh&#xff09;事务日志的写入ES在大数据量下的性能优化 文件系统缓存优化数据预热文档&#xff08;Document&…

名酒新周期,西凤复兴的“四个自信”

执笔 | 文 清 编辑 | 萧 萧 11月18日&#xff0c;四大名酒之一、凤香品类龙头企业的西凤酒&#xff0c;携全系列产品亮相AIIC酒业创新展暨中国名酒成就展。 在当日下午举行的“筑梦新征程”2023中国名酒纪念大会暨《大师》影像志上线仪式上&#xff0c;陕西西凤酒股份有限…

linux网络之网络层与数据链路层

文章目录 一、网络层 1.IP协议 2.IP协议头格式 3.网段划分 4.特殊ip地址 5.IP地址的数量限制 6.私有ip和公网IP 7.路由 二、数据链路层 1.以太网 2.以太网帧格式 3.MAC地址 4.对比理解MAC地址和IP地址 5.MTU 6.ARP协议 ARP协议的工作流程 ARP数据报的格式 7.DNS 8.ICMP协议 9.N…