Qt:实现git中diff的功能

在 Git 中,有四种 diff 算法,即 Myers、Minimal、Patience 和 Histogram,用于获取位于两个不同 commit 中的两个相同文件的差异。

Myers算法实现参考:

Myers‘Diff之贪婪算法_myers算法-CSDN博客

Git Diff 算法详解:Myers Diff Algorithm-腾讯云开发者社区-腾讯云 (tencent.com)

Myers差分算法的理解、实现、可视化 - Oto_G - 博客园 (cnblogs.com)

最后找到一个c++可用的代码如下,在Myers函数中传入两个需要比较的文档内容。

#include <QDir>
#include <QVariantMap>
#include <QVariantList>
#include <QStringList>
#include <QList>
#include <QDebug>namespace ScriptManagerWebNew {
enum MoveType {MoveType_None,MoveType_Down,MoveType_Right,MoveType_Diagonal
};
struct Point {Point(int x, int y) {this->x = x;this->y = y;}bool operator== (const Point& pt) const {return this->x == pt.x && this->y == pt.y;}bool operator!= (const Point& pt) const {return this->x != pt.x || this->y != pt.y;}MoveType operator >(const Point& pt2) {if (this->x == pt2.x && this->y + 1 == pt2.y) {return MoveType_Down;}else if (this->y == pt2.y && this->x + 1 == pt2.x) {return MoveType_Right;}else if (this->x + 1 == pt2.x && this->y + 1 == pt2.y) {return MoveType_Diagonal;}return MoveType_None;}int x = 0;int y = 0;
};QString Myers(QString formerText, QString currentText)
{const auto lines = formerText.split("\n");const auto lines2 = currentText.split("\n");auto n = lines.size();auto m = lines2.size();std::vector<std::map<int, int>> Xlist;//只存储x坐标,y可以由k=x-y算出std::map<int,int> X;//假设起始点(0,-1)X[1] = 0;bool go_ahead = true;//步数d//从0开始,因为d=0时,也可能沿对角线前进for (int d = 0; d <= n + m && go_ahead; d++) {//k-lines: k has odd or even values according to an odd or even dfor (int k = -d; k <= d; k = k + 2) {//判断该从(d-1,k-1)向右走,还是从(d-1,k+1)向下走//当k!=d && k!=-d时, 可以从X[k + 1]向下走, 或者X[k - 1]向右走//具体怎么选择,判断x值:选择x大的,保证删除操作优于添加操作bool down = (k == -d || (k != d && X[k - 1] < X[k + 1]));int kPrev = down ? k + 1 : k - 1;//起始位置int xStart = X[kPrev];int yStart = xStart - kPrev;//中间位置int xTmp = down ? xStart : xStart + 1;int yTmp = xTmp - k;//此次move后的位置int xEnd = xTmp;int yEnd = yTmp;//判断能否总对角线(moving through a diagonal is free)while (xEnd < n && yEnd < m && lines[xEnd] == lines2[yEnd]) {++xEnd;++yEnd;}X[k] = xEnd;//到终点,找到了最短路线if (xEnd >= n && yEnd >= m) {go_ahead = false;break;}}Xlist.push_back(X);}//回退,从终点到起点,找出路线std::vector<Point> path; //move的路线Point pt(lines.length(), lines2.length());path.push_back(pt);for (int d = Xlist.size() - 1; pt.x > 0 || pt.y > 0; --d) {auto X = Xlist[d];int k = pt.x - pt.y;//结束位置int xEnd = X[k];int yEnd = pt.x - k;//结束位置前是否走的对角线while (xEnd > 0 && yEnd > 0 && xEnd <= n && yEnd <= m && lines[xEnd-1] == lines2[yEnd-1]) {--xEnd;--yEnd;path.push_back(Point(xEnd, yEnd));}//down可以确定上一步的k线,对角线上的移动不影响d和k//并且,Xlist[d][k-1] == Xlist[d-1][k-1]; Xlist[d][k+1] == Xlist[d-1][k+1]bool down = (k == -d || (k != d && X[k - 1] < X[k + 1]));int kPrev = down ? k + 1 : k - 1;//起始位置int xStart = X[kPrev];int yStart = xStart - kPrev;中间位置//int xTmp = down ? xStart : xStart + 1;//int yTmp = xTmp - k;path.push_back(Point(xStart, yStart));pt.x = xStart;pt.y = yStart;}path.pop_back();//path第一个点是假设的起点(0,-1);//文字描述path代表的操作QString stream;
//    std::stringstream stream;if (path.size() >= 2) {int size = path.size();for (int i = size - 2; i >= 0; --i) {Point prev_point = path[i+1];MoveType type = prev_point>(path[i]);switch (type) {case MoveType_Right: {stream.append("-" + lines[prev_point.x]+"\n");break;}case MoveType_Down: {stream.append( "+" + lines2[prev_point.y]+"\n");break;}case MoveType_Diagonal: {stream.append(lines[prev_point.x]+"\n");break;}}}}
//    std::cout << "最短编辑路线如下:" << std::endl;
//    std::cout << stream.str();
//    std::string input;
//    std::cin >> input;return stream;
}

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

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

相关文章

深度学习算法集成部署

文章目录 0 Docker容器部署1 制作dockerfile2 新建镜像3 新建容器4 运行脚本5 异常处理0 Docker容器部署 使用 Docker 容器部署深度学习模型有以下几个主要优势: 环境一致性:Docker 容器可以将应用程序及其所需的依赖项打包在一起,确保应用程序在不同环境中的运行一致性。这对…

为什么在二三十岁时应该努力变强大?

一、对于即将三十岁或三十岁的人的建议&#xff0c;包括举重、跑步、学习等健身技能&#xff0c;以及在生活中如何处理困难和挑战。 举重是二三十岁的人的最佳做法之一 学习如何在身体上、感情上和精神上挑战极限 在城市里寻找机会&#xff0c;接受邀请&#xff0c;强迫自己出去…

C++之Eigen库基本使用

目录 1、矩阵的构造和初始化操作 2、矩阵的算术运算 3、矩阵的分解和求解 4、矩阵的变换 5、矩阵的访问和修改 6、矩阵遍历 7、线性方程组求解 8、其他操作 Eigen库是一个高级的C库&#xff0c;用于线性代数&#xff0c;矩阵和向量运算&#xff0c;数值分析和相关的数学…

【智能算法】人工原生动物优化算法(APO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.获取代码 1.背景 2024年&#xff0c;X Wang受到自然界原生动物启发&#xff0c;提出了人工原生动物优化算法&#xff08; Artificial Protozoa Optimizer, APO&#xff09;。 2.算法原理 2.1算法思想 AP…

压缩归档库-Snappy介绍

1.简介 Snappy 是一个 C 编写的压缩和解压缩库&#xff0c;由 Google 开发。它专为速度而设计&#xff0c;而不是最大压缩率或与其他压缩库的兼容性。 Snappy 通常用于需要快速压缩和解压缩的场景。 Snappy具有以下属性&#xff1a; 快速&#xff1a;压缩速度达到250 MB/秒及…

数智化快速开发平台

助力企业IT规划标准化&#xff0c;实现企业IT生态化 目前市场上有很多面向企业各种业务场景的产品&#xff0c;这些产品给企业管理带来便利性的同时&#xff0c;也带来了一系列问题&#xff0c;例如&#xff1a; 不同系统的后台管理功能基本一致&#xff0c;却需要重复建设&a…

linux调试

文章目录 1. 使用打印来调试1.1 重定向1.2 标准预定义宏1.3 日志代码 2. 内核异常2.1 内核打印2.1.1 打印级别2.1.2 跟踪异常2.1.3 动态打印2.1.4 RAM console 2.2 OOPS2.2.1 有源代码的情况2.2.2 没有源代码的情况 3 查看日志4 工具调试 1. 使用打印来调试 1.1 重定向 2>…

代码随想录学习Day 33

动态规划理论基础 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#x…

[Collection与数据结构] Map与Set(一):二叉搜索树与Map,Set的使用

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

python socket通讯 学习记录

python socket 1. 初级实现2. 添加header3. 中级实现&#xff08;引用pickle库&#xff09;4. 高级实现&#xff08;相互发送信息&#xff09;5. 一点尝试5. 1个server对应2个client5.2个server对应1个client 名称版本python3.11 本文涉及到socket的server与client通讯从简单到…

LeetCode 257. 二叉树的所有路径

LeetCode 257. 二叉树的所有路径 1、题目 题目链接&#xff1a;257. 二叉树的所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root…

java.net.SocketInputStream.socketRead0 卡死导致 tomcat 线程池打满的问题

0 TL;DR; 问题与原因&#xff1a;某些特定条件下 java.net.SocketInputStream.socketRead0 方法会卡死&#xff0c;导致运行线程一直被占用导致泄露采用的方案&#xff1a;使用监控线程异步监控卡死事件&#xff0c;如果发生直接关闭网络连接释放链接以及对应的线程 1. 问题 …

【视频格式转换】【ffmepg】对mp4文件进行重新编码输出新的mp4文件

【视频格式转换】【ffmepg】对mp4文件进行重新编码输出新的mp4文件 背景 之前开发调试了个能正常调用ffmpeg解码mp4文件得到yuv数据的testbed(把ffmpeg开源库移植并交叉编译到一个嵌入式平台)&#xff0c;用了好几年了&#xff0c;今天用来挂测一批新的采集视频mp4文件&#x…

nacos下载安装和nacos启动报错

nacos简介: Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您…

YOLOv9中模块总结补充|RepNCSPELAN4详图

专栏地址&#xff1a;目前售价售价69.9&#xff0c;改进点70 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 1. RepNCSPELAN4详图 RepNCSPELAN4是YOLOv9中的特征提取-融合模块&#xff0c;类似前几…

【数据结构-二叉搜索树的增删查改】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 …

C#面试题: 寻找中间值

给定一个数组&#xff0c;在区间内从左到右查找中间值&#xff0c;每次查找最小值与最大值区间内的中间值&#xff0c;且这个区间元素数量不小于3。 例如 1.给定数组float[] data { 1, 2.3f, 4, 5.75f, 8.125f, 10.5f, 13, 15, 20 } 输出&#xff1a;10.5、5.75、4、2.3、8…

[虚拟机+单机]梦幻契约H5修复版_附GM工具

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 视频演示 [虚拟机单…

vue2人力资源项目2登录接口、跳转主页

用户名和密码 解决跨域问题 1.在vue.config.js里配置 proxy: {// 如果请求地址里有api&#xff0c;就转成这个地址/api: {target: https://heimahr.itheima.net/}}// before: require(./mock/mock-server.js)}, axios封装 utils/request.js import axios from axios// creat…

Linux-信号执行

1. 信号什么时候被处理 当进程从内核态返回到用户态的时候&#xff0c;进行信号的检测和处理 什么内核态&#xff0c;什么又是用户态呢&#xff1f; 当进程在CPU上运行时&#xff0c;内核态&#xff1a;允许进程访问操作系统的代码和数据&#xff0c;用户态&#xff1a;进程只…