diff git 代码实现_Git diff 算法

在Git中,有四种diff算法,即Myers,Minimal,Patience和Histogram。默认Myers。Minimal是Myers的改进,Histogram是Patience的改进。Myers总是通过完全相同的行来实现匹配,它的问题在于可能会有大量的空行和括号影响结果。Histogram通过“少量的独特的行”做锚定,来更合适的标记代码段的移动。

Myers算法我觉得这个文章讲的非常好:

https://www.dazhuanlan.com/2019/12/05/5de8b95bf1dba/?__cf_chl_captcha_tk__=543b5104e7fd004468911afb048ec39aa0825007-1602557816-0-AW3rYqpZ0emcbioiQkuXhPmDNLL664JohKrR6_NXEyU2IKEgbxnO4LLWbSksogDlpyYU6MvtrWuKzKAZZkjUVpK49_0Ngeb6k6e_yyoyX5Ga8edOjvvbMO2-5geYPYu3rYCSktaDOZMeqRzih89lENvLSF14lV1PEizy0XLRBkIjL7w2_II0wnmIOZe0mfNV4nDMn4PP1IGUkP5WfNK9JmFcaPKZA8RGQYoubsUN52tBShJGgMbkcc1u1SF8nJXpsulDbjHzbr1SECdmMOBV6qImrI5JVlQlUfRz4xpNkUEwUAHGmSuClZeHmRrBSRxtJrOE0SNoWgxM5sj8uQPOdA52UukFoFVQ_g2kTRLMoFBM1HDgkbWhcR00jFf4j1A2uQ

大体思路就是一个贪心的BFS,向右或者向下算新的一层,走对角线不算新的一层。但是这种方法,在最坏的情况下,时空复杂度好像还是n^2

下面的链接讲了Patience和Histogram的区别

https://stackoverflow.com/questions/32365271/whats-the-difference-between-git-diff-patience-and-git-diff-histogram

下面的链接讲了Histogram的实现:

https://link.springer.com/article/10.1007/s10664-019-09772-z

大概意思就是先找到出现次数最少但是在修改前后都出现的行,对这些行做LCS(这时候是一个子任务集,规模比较小)。然后递归的对被这些行分割的区域做一样的操作。

另外,按行做diff算法,现在看起来,就是求一个LCS,在用Myers的时候,不明白大家为什么不直接用nlogn的LCS来做。。。

https://blog.csdn.net/accelerator_/article/details/11339459

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Git diff算法是一种比较两个文件或者两个版本之间差异的算法,Java中可以通过实现这个算法实现git diff功能。下面是Java实现git diff算法的步骤: 1.将两个文件分别读入内存中,并将其转换为字符串。 2.将两个字符串按照行进行分割,并将每一行的内容存储到一个数组中。 3.使用动态规划算法,计算出两个字符串之间的最长公共子序列。 4.根据最长公共子序列,生成差异报告。 5.将差异报告输出到控制台或者文件中。 下面是Java实现git diff算法代码示例: ```java import java.util.ArrayList; import java.util.List; public class GitDiff { public static void main(String[] args) { String str1 = "xxxxxxxxxx"; String str2 = "yyyyyyyyyy"; List<String> list1 = splitString(str1); List<String> list2 = splitString(str2); int[][] dp = new int[list1.size() + 1][list2.size() + 1]; for (int i = 1; i <= list1.size(); i++) { for (int j = 1; j <= list2.size(); j++) { if (list1.get(i - 1).equals(list2.get(j - 1))) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); } } } List<String> result = new ArrayList<>(); int i = list1.size(); int j = list2.size(); while (i > 0 && j > 0) { if (list1.get(i - 1).equals(list2.get(j - 1))) { i--; j--; } else if (dp[i - 1][j] >= dp[i][j - 1]) { result.add("delete " + list1.get(i - 1)); i--; } else { result.add("add " + list2.get(j - 1)); j--; } } while (i > 0) { result.add("delete " + list1.get(i - 1)); i--; } while (j > 0) { result.add("add " + list2.get(j - 1)); j--; } for (int k = result.size() - 1; k >= 0; k--) { System.out.println(result.get(k)); } } private static List<String> splitString(String str) { List<String> list = new ArrayList<>(); String[] arr = str.split("\n"); for (String s : arr) { list.add(s); } return list; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值