当前位置: 首页 > article >正文

使用求2个字符串最长公共子序列的方法来实现 git diff 算法 java 实现

测试类 GitDiffTest2.java:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class GitDiffTest2 {
    private static String folder = "\\xxx\\";

    private static List<String> lines_v1 = loadTxtFile2List(folder + "DemoClass1.java" );
    private static List<String> lines_v2 = loadTxtFile2List(folder + "DemoClass2.java");

    public static void main(String[] args) {

       /* lines_v1 = new ArrayList<>();
        lines_v2 = new ArrayList<>();
        lines_v1.add( "m" );
        lines_v1.add( "o" );
        lines_v1.add( "t" );
        lines_v1.add( "h" );
        lines_v1.add( "e" );
        lines_v1.add( "r" );

        lines_v2.add( "m" );
        lines_v2.add( "o" );
        lines_v2.add( "n" );
        lines_v2.add( "s" );
        lines_v2.add( "t" );
        lines_v2.add( "e" );
        lines_v2.add( "r" );*/

        int size_v1 = lines_v1.size();
        int size_v2 = lines_v2.size();
        int[][] dp = new int[size_v1][size_v2];
        for (int index_v1 = 0; index_v1 < size_v1; index_v1++) {
            for (int index_v2 = 0; index_v2 < size_v2; index_v2++) {
                String line_v1 = lines_v1.get(index_v1);
                String line_v2 = lines_v2.get(index_v2);
                if ( line_v1.equals( line_v2 ) ) {
                    if( index_v1 == 0 || index_v2 == 0 ){
                        // v1:...a
                        // v2:   a
                        dp[index_v1][index_v2] = 1;
                    }else {
                        // v1:...a
                        // v2:...a
                        dp[index_v1][index_v2] = dp[index_v1 - 1][index_v2 - 1] + 1;
                    }
                } else {
                    if( index_v1==0 || index_v2==0 ){
                        // v1:...a
                        // v2:   b
                        dp[index_v1][index_v2] = 0;
                    }else {
                        // v1:...a
                        // v2:...b

                        // v1: ...   a
                        // v2:...b        此时,v1 的 a 前面的部分 "..." 和 v2 的 "...b" 来求最长公共子串长度
                        int lcs1 = dp[index_v1 - 1][index_v2];

                        // v1:...a
                        // v2: ...   b    此时,v2 的 b 前面的部分 "..." 和 v1 的 "...a" 来求最长公共子串长度
                        int lcs2 = dp[index_v1][index_v2 - 1];

                        dp[index_v1][index_v2] = Math.max( lcs1,lcs2 );
                    }
                }
            }
        }


        List<String> result = new ArrayList<>();
        int index_v1 = lines_v1.size() - 1;
        int index_v2 = lines_v2.size() - 1;

        while (index_v1 >= 0 && index_v2 >= 0) {
            String line_v1 = lines_v1.get(index_v1);
            String line_v2 = lines_v2.get(index_v2);
            if ( line_v1.equals( line_v2 ) ) {
                // v1:..... a
                // v2:  ... a
                // 原封不动的输出行 a,因为 新旧版本文本中都有 a 行
                result.add( "  " + line_v1 );
                index_v1--;
                index_v2--;
            }else {
                // v1:..... a
                // v2:  ... b

                // v1:  ..... a
                // v2:  ... b      如果 lcs1 更长,则最长公共子串中不包含 行a,意味着 v2版本中需要删除v1版本中的行a
                int lcs1 = dp[index_v1 - 1][index_v2];

                // v1:..... a
                // v2:    ... b    如果 lcs2更长,则最长公共子串中不包含行b,意味着v2版本中需要新增 行b
                int lcs2 = dp[index_v1][index_v2-1];

                if ( lcs1 > lcs2 ) {
                    result.add( "- " + line_v1 );
                    index_v1--;
                } else {
                    result.add( "+ " + line_v2 );
                    index_v2--;
                }
            }
        }
        while (index_v2 >= 0) {
            result.add("+ " + lines_v2.get(index_v2));
            index_v2--;
        }
        while (index_v1 >= 0) {
            result.add("- " + lines_v1.get(index_v1));
            index_v1--;
        }
        for (int k = result.size() - 1; k >= 0; k--) {
            System.out.println(result.get(k));
        }
    }

    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) {
                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();
                }
            }
        }
    }
}

旧版本文本样例文件 DemoClass1.java:

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 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) {
        return null;
    }

    public static double calculateSimilarity( String str1,String str2 ){
        try {
            int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
            double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
            return similarity;
        }catch ( Exception e ){
            e.printStackTrace();
            return 0d;
        }
    }
}

测试输出:

  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();
+     private static final LevenshteinDistance LEVENSHTEIN_DISTANCE2 = LevenshteinDistance.getDefaultInstance();
  
      public static String null2emptyWithTrim( String str ){
-         if( str == null ){
-             str = "";
-         }
-         str = str.trim();
+         // 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;
+         return null;
      }
  
      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;
+         try {
+             int distance = LEVENSHTEIN_DISTANCE.apply(str1, str2);
+             double similarity = 1 - (double) distance / Math.max(str1.length(), str2.length());
+             return similarity;
+         }catch ( Exception e ){
+             e.printStackTrace();
+             return 0d;
+         }
      }
  }


http://www.kler.cn/news/157126.html

相关文章:

  • Kotlin学习之集合
  • 使用JAVA语言写一个排队叫号的小程序
  • C++ 系列 第四篇 C++ 数据类型上篇—基本类型
  • 数据结构学习笔记——广义表
  • 实体、协议、服务和服务访问点
  • 【重点】【滑动窗口】239. 滑动窗口最大值
  • Appium:iOS部署
  • 深度学习在训练时更新和保存最佳训练结果的方法(字典方法,本地保存方法,模型深拷贝方法)
  • selenium中元素定位正确但是操作失败,6种解决办法全搞定
  • 六、ZooKeeper Java API操作
  • 【数据结构】——栈|队列(基本功能)
  • Python字符串模糊匹配工具:TheFuzz 库详解
  • 关于使用百度开发者平台处理语音朗读问题排查
  • Spring-Security取消验证-Get请求接口正常,Post请求报错403
  • java后端技术演变杂谈(未完结)
  • c语言笔记之小项目家庭收支记账软件
  • java synchronized详解
  • ruby安装(vscode、rubymine)
  • 「Qt Widget中文示例指南」如何创建一个计算器?(二)
  • 深度学习(五):pytorch迁移学习之resnet50
  • MySQL安装,建立,导入本地Txt文件
  • 寻找两个有序数组的中位数算法(leetcode第4题)
  • Android 7.1 点击清空全部按钮清空一切运行进程(包括后台在播音乐)
  • 【Linux】进程控制--进程创建/进程终止/进程等待/进程程序替换/简易shell实现
  • CPP-SCNUOJ-Problem P29. [算法课指针] 颜色分类,小白偏题超简单方法
  • 前端---JavaScript篇
  • 【LeeCode】链表总结
  • 大数据之Redis
  • Python按要求从多个txt文本中提取指定数据
  • 卷积神经网络(CNN):艺术作品识别