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 d
        for (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.mfbz.cn/a/610130.html

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

相关文章

自动驾驶系统中的数据闭环:挑战与前景

目录 自动驾驶概况 1.1自动驾驶分级 1.2自动驾驶国内发展 ​1.3自动驾驶架构模型 数据闭环的意义 2.1 搜集corner case的数据 2.2 提高模型的泛化能力 2.3 驱动算法迭代 数据闭环落地的痛点及对策 3.1 数据采集和使用的合规性问题 3.2 数据确权问题 3.3 数据采集…

【经验总结】 常用的模型优化器

优化器是一种用于优化模型权重和偏差的算法&#xff0c;它根据训练数据更新模型参数&#xff0c;以模型的预测结果更加准确。 1. 常见的优化器 SGD&#xff08;Stochastic Gradient Descent&#xff09;&#xff1a;SGD是一种基本的优化算法&#xff0c;它在每次迭代中随机选择…

揭秘Ping32如何实现上网行为监控

企业上网行为管理软件在现代企业管理中扮演着举足轻重的角色。它不仅能够监控和记录员工的上网行为&#xff0c;还能有效防止数据泄露和不当使用&#xff0c;从而保障企业的信息安全。 一、Ping32上网监控软件的具体功能包括&#xff1a; 1.网页浏览监控&#xff1a;对Chrome…

jvm面试题30问

什么是JVM的跨平台&#xff1f; 什么是JVM的语言无关性&#xff1f; 什么是JVM的解释执行 什么是JIT? JIT&#xff1a;在Java编程语言和环境中&#xff0c;即时编译器&#xff08;JIT compiler&#xff0c;just-in-time compiler&#xff09;是一个把Java的字节码&#xff08;…

流量卡就该这么选,用起来性价比真的超高!

很多朋友会私信小编&#xff0c;让小编给大家推荐几款流量卡&#xff0c;在这里小编告诉大家&#xff0c;流量卡可以推荐&#xff0c;但是每个人的喜好不同&#xff0c;小编也忙不过来&#xff0c;今天&#xff0c;小编整理了一篇选购指南&#xff0c;大家可以参考选择&#xf…

2024 B2B企业出海营销白皮书(展会篇)

来源&#xff1a;科特勒&微吼 根据36氪研究院发布的《2023-2024年中国企业出海发展研究报告》中指出&#xff0c;随着全球化浪潮席卷以及中国智造的崛起&#xff0c;中国企业出海主力从过去的低附加值行业逐步扩展至信息技术、先进制造、医疗健康、汽车交通、新消费等附加…

106短信平台疑难解答:为何手机正常却收不到短信?

当您使用群发短信平台发送消息时&#xff0c;有时尽管系统提示发送成功&#xff0c;但手机却未能收到短信。这背后可能隐藏着一些不为人知的原因。 首先&#xff0c;我们要明确&#xff0c;在正常情况下&#xff0c;只要手机状态正常&#xff0c;都应该能够接收到短信。然而&am…

为什么站长们喜欢使用新加坡站群服务器呢?

为什么站长们喜欢使用新加坡站群服务器呢? 站群优化一直是站长们追逐的目标之一&#xff0c;而新加坡站群服务器则备受站长们的青睐。为什么会如此呢?让我们深入了解一下。 为什么站长们喜欢使用新加坡站群服务器呢? 站群&#xff0c;简单来说&#xff0c;就是一组相互关联…

Python专题:十、字典(1)

数据类型:字典,是一个集合性质的数据类型 字典的初始化 字典{关键字:数值} 新增元素 修改元素 字典元素访问 字典[关键字} in 操作符 字典关键字检测 字典元素遍历 ①遍历关键字

Android build.prop生成过程源码分析

Android的build.prop文件是在Android编译时刻收集的各种property【LCD density/语言/编译时间, etc.】&#xff1b;编译完成之后&#xff0c;文件生成在out/target/product/<board【OK1000】>/system/目录下&#xff1b;在Android运行时刻可以通过property_get()[c/c域] …

深度学习论文: LightGlue: Local Feature Matching at Light Speed

深度学习论文: LightGlue: Local Feature Matching at Light Speed LightGlue: Local Feature Matching at Light Speed PDF: https://arxiv.org/pdf/2306.13643 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://github.com/shanglianlm0525/…

python数据分析——数据预处理

数据预处理 前言一、查看数据数据表的基本信息查看info&#xff08;&#xff09;示例 查看数据表的大小shape&#xff08;&#xff09;示例 数据格式的查看type()dtype&#xff08;&#xff09;dtypes&#xff08;&#xff09;示例一示例二 查看具体的数据分布describe()示例 二…

机器人学【一、刚体运动】

机器人学 文章目录 机器人学1. 刚体运动1.1 刚体变换刚体刚体变换 1.2 三维空间中的旋转运动群求质点坐标的相对变换旋转矩阵的合成法则用线性算子来计算叉积叉积的右手法则叉积用于计算线速度旋转的指数坐标Rodrigues公式计算旋转矩阵的例子四元数 1.3 三维空间中的刚体运动齐…

二分查找入门、二分查找模板

二分查找的具体实现是一个难点&#xff0c;挺复杂的&#xff0c;可以背住一个模板&#xff0c;然后以后再慢慢学习。下面是y总的二分模板(比较难懂&#xff0c;之后再学) y总的模板 二分的本质是在一个边界内&#xff0c;定义了两种不同的形状&#xff0c;其中某点是这两个性…

Golang | Leetcode Golang题解之第68题文本左右对齐

题目&#xff1a; 题解&#xff1a; // blank 返回长度为 n 的由空格组成的字符串 func blank(n int) string {return strings.Repeat(" ", n) }func fullJustify(words []string, maxWidth int) (ans []string) {right, n : 0, len(words)for {left : right // 当前…

详细解析DBC文件

《AUTOSAR谱系分解(ETAS工具链)》之总目录_autosar的uart模块-CSDN博客

Docker Desktop 修改容器的自启动设置

Docker Desktop 允许用户控制容器的自启动行为。如果你不希望某个容器在 Docker 启动时自动启动&#xff0c;你可以通过以下步骤来更改设置&#xff1a; 1. 打开 Docker Desktop 应用。 2. 点击右上角的设置&#xff08;Settings&#xff09;按钮&#xff0c;或者使用快捷键 Cm…

Hive Aggregation 聚合函数

Hive Aggregation 聚合函数 基础聚合 增强聚合

找最大数字-第12届蓝桥杯国赛Python真题解析

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第60讲。 找最大数字&#…

67万英语单词学习词典ACCESS\EXCEL数据库

这似乎是最多记录的英语单词学习词典&#xff0c;包含复数、过去分词等形式的单词。是一个针对想考级的人员辅助背单词学英语必备的数据&#xff0c;具体请自行查阅以下的相关截图。 有了数据才能想方设法做好产品&#xff0c;结合权威的记忆理论&#xff0c;充分调动用户的眼…
最新文章