Qt:实现git中diff的功能

2024-05-10 08:52
文章标签 实现 qt 功能 git diff

本文主要是介绍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;
}

这篇关于Qt:实现git中diff的功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/975988

相关文章

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Mysql实现范围分区表(新增、删除、重组、查看)

《Mysql实现范围分区表(新增、删除、重组、查看)》MySQL分区表的四种类型(范围、哈希、列表、键值),主要介绍了范围分区的创建、查询、添加、删除及重组织操作,具有一定的参考价值,感兴趣的可以了解... 目录一、mysql分区表分类二、范围分区(Range Partitioning1、新建分区表:2、分

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC