javascript 版 WinMerge

WinMerge.html:

<!DOCTYPE html>
<html>
<head><title>WinMerge</title><meta charset="UTF-8">
</head>
<body>
<h1>文件比较</h1>
<form><label for="file1">旧版本:</label><input type="file" id="file1" name="file1"><br><br><label for="file2">新版本:</label><input type="file" id="file2" name="file2"><br><br><button type="button" onclick="compare()">开始比较</button>
</form><div id = "div_info" style="width:1000px;height:500px;border:1px solid gray;overflow:auto">
</div><script>var infoDiv = document.getElementById("div_info");function compare() {var file1 = document.getElementById("file1").files[0];var file2 = document.getElementById("file2").files[0];var reader1 = new FileReader();var reader2 = new FileReader();reader1.readAsText(file1);reader2.readAsText(file2);var lines_v1 = null;var lines_v2 = null;reader1.onload = function() {lines_v1 = reader1.result.split('\n');// printArray( lines_v1 );reader2.onload = function() {lines_v2 = reader2.result.split('\n');// printArray( lines_v2 );// 比较两个文档的区别docDiff( lines_v1,lines_v2 );}}
}function printArray( array ){var len = array.length;for (let i = 0; i < len; i++){console.log( "[" + array[ i ] + "]" );}
}function docDiff( lines_v1,lines_v2 ){var dp = calculateShortestEditDistance(lines_v1, lines_v2);var index1 = lines_v1.length - 1;var index2 = lines_v2.length - 1;console.log("一共需要" + dp[ index1 ][ index2 ] + "步编辑操作");var results = [];while ( index1 >= 0 && index2 >= 0 ){var line_v1 = lines_v1[ index1 ];var line_v2 = lines_v2[ index2 ];if( line_v1 == line_v2 ){// v1:...a// v2:...a// 原封不动的输出results.push( " " + line_v1 );index1--;index2--;}else {// v1:...a// v2:...b// v1:... a// v2:... b// 此时,a修改修改为bvar  sed1 = 0;if( index1 > 0 && index2 >0 ){sed1 = dp[index1 - 1][index2 - 1];}// v1:...a// v2: ... b// 此时,需要插入bvar sed2 = 0;if( index2 >0 ){sed2 = dp[index1][index2 - 1];}// v1: ... a// v2:...b// 此时,需要删除avar sed3 = 0;if( index1 > 0 ){sed3 = dp[index1-1][index2];}var sed = Math.min( sed1,sed2,sed3 );if( sed == sed1 ){// results.add( "edit   " + line_v2 + " DIFF:" + StringDiffTest.diff( line_v1,line_v2 ) );// var diffInfo = StringDiffTest.diff(line_v1, line_v2);// results.add( "edit   " + diffInfo );results.push( "+ " + line_v2 );results.push( "- " + line_v1 );index1--;index2--;}else if( sed == sed3 ){results.push( "- " + line_v1 );index1--;}else if( sed == sed2 ){results.push( "+ " + line_v2 );index2--;}}}while ( index2 >= 0 ){// v2 中多出的 "首行们" 都是需要被插入的results.push( "+ " + lines_v2[ index2 ] );index2--;}while ( index1 >= 0 ){// v1 中多出的 "首行们" 都是需要删除的results.push( "- " + lines_v1[ index1 ] );index1--;}for ( var i=results.length -1;i>=0;i-- ){var line = results[ i ];var small = document.createElement( "small" );small.innerHTML = line;if( line.startsWith( "-" ) ){small.style.color = "red";}else if( line.startsWith( "+" ) ){small.style.color = "green";}infoDiv.appendChild( small );infoDiv.appendChild( document.createElement( "br" ) );}
}// 返回 int[][]
function calculateShortestEditDistance( lines_v1,lines_v2 ){// dp[i][j] 表示的是将 lines_v1 的前i个元素变换为 lines_v2 中的前j个元素需要使用的最优( 即需要转换步骤最少 )的转换方式var size_v1 = lines_v1.length;var size_v2 = lines_v2.length;var dp = createArray( size_v1,size_v2 );for (var index1 = 0; index1 < size_v1; index1++) {var line_v1 = lines_v1[ index1 ];for (var index2 = 0; index2 < size_v2; index2++) {var line_v2 = lines_v2[ index2 ];if( index1 == 0 ){if( index2 == 0 ){if( line_v1 == line_v2 ){// v1:a// v2:adp[ index1 ][ index2 ] = 0;}else {// v1:a// v2:bdp[ index1 ][ index2 ] = 1;}}else {if( contains( lines_v2,line_v1,0,index2 ) ){// v1:      a// v2:...a...   size =  index2 + 1// v1转换为 v2需要 size - 1步( 也就是 index2步 )插入操作dp[ index1 ][ index2 ] = index2;}else {// v1:      a// v2:...b...   size =  index2 + 1// v1转换为 v2需要 1步编辑操作,size-1= index2 步插入操作,一共index2 + 1步操作dp[ index1 ][ index2 ] = index2 + 1;}}}else {if( index2 == 0 ){if( contains(lines_v1, line_v2, 0, index1) ){// v1:....a...  size = index1 + 1// v2:       a// v1转换为 v2需要 size-1=index1步删除操作dp[ index1 ][ index2 ] = index1;}else {// v1:....a...  size = index1 + 1// v2:       b// v1转换为 v2需要 1步编辑操作和size-1=index1步删除操作,一共index1+1步操作dp[ index1 ][ index2 ] = index1 + 1;}}else {if( line_v1 == line_v2 ){// v1:...a// v2:...adp[ index1 ][ index2 ] = dp[ index1 - 1 ][ index2 - 1 ];}else {// v1:...a// v2:...b// v1:... a// v2:... b// 此时 v1 的前部分和 v2的前部分做dp运算,a修改为bvar sed_prev1 = dp[ index1 - 1 ][ index2 - 1 ];// v1: ... a// v2:...b// 此时v1的前部分和v2做dp运算,删除avar sed_prev2 = dp[ index1 - 1 ][ index2 ];// v1: ...a// v2:  ... b// 此时 v1和v2的前部分做dp运算,插入bvar sed_prev3 = dp[ index1 ][ index2 - 1 ];dp[ index1 ][ index2 ] = Math.min( sed_prev1,sed_prev2,sed_prev3 ) + 1;}}}}}return dp;
}// todo 测试行列是否写反了
function createArray(rowCount, colCount) {var arr = [];for (var i = 0; i < rowCount; i++) {arr[i] = [];for (var j = 0; j < colCount; j++) {arr[i][j] = 0;}}return arr;
}function contains(lines, targetLine, beginIndex, endIndex) {for (var i = beginIndex; i <=endIndex ; i++) {if( lines[ i ] == targetLine ){return true;}}return false;
}
</script>
</body>
</html>

测试效果:

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

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

相关文章

【Idea】八种Debug模式介绍

1.行断点 在对应的代码行左侧边栏点击鼠标左键&#xff0c;会出现一个红色圆圈&#xff0c;以debug模式执行时当代码运行到此处则会停止&#xff0c;并可以查询相关上下文参数 2.方法断点 在方法左侧点击创建断点,在方法进入时会停止&#xff0c;同时可以右键断点&#xff0c;…

修改Android打包apk的名字和目录

app打包生成apk后通常需要进行备份&#xff0c;但是要区分好哪个apk是什么版本的、什么时候打包的&#xff0c;以方便以后区分使用。 最开始的想法是把版本号、创建时间这些加在apk文件名上即可&#xff0c;但是公司要求apk使用一个固定的名称&#xff0c;那我怎么保存版本号信…

【CSP】2022-03-3 计算资源调度器 stl大模拟使用map优化索引 完整思路+完整的写代码过程(遇到的问题)+完整代码

2022-03-3 计算资源调度器 stl大模拟使用map优化索引 2022-03-3 计算资源调度器 stl大模拟使用map优化索引思路写代码的过程&#xff08;遇到的问题&#xff09;完整代码 2022-03-3 计算资源调度器 stl大模拟使用map优化索引 在联系了之前那么多道stl大模拟题后&#xff0c;终…

德人合科技|天锐绿盾加密软件——数据防泄漏系统

德人合科技是一家专注于提供企业级信息安全解决方案的服务商&#xff0c;提供的天锐绿盾加密软件是一款专为企业设计的数据安全防护产品&#xff0c;主要用于解决企事业单位内部敏感数据的防泄密问题。 www.drhchina.com PC端&#xff1a; https://isite.baidu.com/site/wjz012…

Redis精讲

redis持久化 RDB方式 Redis Database Backup file (redis数据备份文件), 也被叫做redis数据快照. 简单来说就是把内存中的所有数据记录到磁盘中. 快照文件称为RDB文件, 默认是保存在当前运行目录. [rootcentos-zyw ~]# docker exec -it redis redis-cli 127.0.0.1:6379> sav…

速卖通商品采集API:关键字搜索商品item_search、获取商品详情item_get

item_get-获得aliexpress商品详情 item_search-按关键字搜索aliexpress商品 公共参数 请求地址: aliexpress.item_search/aliexpress.item_get 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是…

03-安装配置jenkins

一、安装部署jenkins 1&#xff0c;上传软件包 为了方便学习&#xff0c;本次给大家准备了百度云盘的安装包 链接&#xff1a;https://pan.baidu.com/s/1_MKFVBdbdFaCsOTpU27f7g?pwdq3lx 提取码&#xff1a;q3lx [rootjenkins ~]# rz -E [rootjenkins ~]# yum -y localinst…

windows下pytorch的dataloader多进程(num_workers)问题,为何num_workers的值只能为0?

问题背景介绍 本人是windows系统&#xff0c;在使用torch.utils.data.Dataloader加载torchvision中的数据集时&#xff0c;将其中的形参num_workers设置为了大于0的数&#xff0c;然后出现以下错误。 原因 在 Windows 系统下&#xff0c;num_workers 参数在使用 PyTorch 的 t…

记一次 .NET某设备监控自动化系统 CPU爆高分析

一&#xff1a;背景 1. 讲故事 先说一下题外话&#xff0c;一个监控别人系统运行状态的程序&#xff0c;结果自己出问题了&#xff0c;有时候想一想还是挺讽刺的&#xff0c;哈哈&#xff0c;开个玩笑&#xff0c;我们回到正题&#xff0c;前些天有位朋友找到我&#xff0c;说…

VideoDubber时长可控的视频配音方法

本次分享由中国人民大学、微软亚洲研究院联合投稿于AAAI 2023的一篇专门为视频配音任务定制的机器翻译的工作《VideoDubber: Machine Translation with Speech-Aware Length Control for Video Dubbing》。这个工作将电影或电视节目中的原始语音翻译成目标语言。 论文地址&…

购买须知:腾讯云服务器99元一年限制月流量300GB

腾讯云99元服务器限制月流量吗&#xff1f;是的&#xff0c;限制月流量&#xff0c;每月提供300GB月流量&#xff0c;超出部分的流量&#xff0c;需要额外支付流量费&#xff0c;价格为0.8元每GB。可以在腾讯云百科 txy.wiki 查看当前99元服务器详细配置和最新的优惠券信息。如…

linux上安装fastdfs及配置

一、基础环境准备 1、所需软件 名称说明libfastcommonfastdfs分离出的一些公用函数包fastdfsfastdas软件包fastdfs-nginx-modulefastdfst和nginx的关联模块nginxnginxl软件包 2、编辑环境 安装一些基础的支持环境 yum install git gccc gcc-c make automake autoconf libto…

复制表

目录 复制表 将部门 30 的所有员工信息保存在 emp30 表中 将复杂查询结果创建为表 只将 emp 表的结构复制为 empnull 表 从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 复制表 严格来说&#xff0c;复制表不是复制操作&am…

Node.Js编码注意事项

Node.js 中不能使用 BOM 和 DOM 的 API&#xff0c;可以使用 console 和定时器 APINode.js 中的顶级对象为 global&#xff0c;也可以用 globalThis 访问顶级对象 浏览器端js的组成 Node.js中的JavaScript组成 相比较之下发现只有console与定时器是两个API所共有的&#xff…

Graphpad Prism10.2.1(395) 安装教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常专业强大的科研医学生物数据处理绘图软件&#xff0c;它可以将科学图形、综合曲线拟合&#xff08;非线性回归&#xff09;、可理解的统计数据、数据组织结合在一起&#xff0c;除了最基本的数据统计分析外&#xff0c;还能自动生成统…

windows server 2019 服务器配置的方法步骤

一、启用远程功能二、测试三、解决多用户登录的问题 一、启用远程功能 右键点击【此电脑】–【属性】&#xff0c;进入“【控制面板\系统和安全\系统】”&#xff0c;点击-【远程设置】(计算机找不到就使用【winE】快捷键) 2、在“远程桌面”下方&#xff0c;点击【允许远程连…

多核多cluster多系统之间缓存一致性概述

目录 1.思考和质疑2.怎样去维护多核多系统缓存的一致性2.1多核缓存一致性2.2多Master之间的缓存一致性2.3dynamIQ架构同一个core中的L1和L2 cache 3.MESI协议的介绍4.ACE维护的缓存一致性5.软件定义的缓存和替换策略6.动图示例 本文转自 周贺贺&#xff0c;baron&#xff0c;代…

StableDiffusion3 官方blog论文研究

博客源地址&#xff1a;Stable Diffusion 3: Research Paper — Stability AI 论文源地址&#xff1a;https://arxiv.org/pdf/2403.03206.pdf Stability.AI 官方发布了Stable diffusion 3.0的论文研究&#xff0c;不过目前大家都沉浸在SORA带来的震撼中&#xff0c;所以这个水…

JavaScript基础Ⅱ

接上文 JavaScript基础Ⅰ JavaScript基础Ⅰ-CSDN博客 目录 第2章 JavaScript基础语法(掌握) 11-JS代码调试 12-JS函数 第3章 JS事件 14-事件的绑定方式 常用事件(了解) 15-常用事件 第4章 JS内置对象(掌握) 16-数组 17-日期 18-数学运算 19-数字 20-全局函数 第2章…

CrossOver2024实现Mac/Linux上快速运行Win软件和游戏

作为软件产品专家&#xff0c;我对各类软件都有较为深入的了解&#xff0c;下面介绍CrossOver2024这款软件的功能特点。 CrossOver2024是一款功能强大的类虚拟机软件&#xff0c;它的设计目标是在Mac和Linux系统上实现Windows软件和游戏的快速运行。这款软件不仅具有出色的兼容…