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.mzph.cn/news/736745.shtml

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

相关文章

自然语言处理(NLP)—— 词义消歧与词语相似性(Word similarity)

1. 词义消歧 1.1 词义消歧的概念 词义消歧&#xff08;Word Sense Disambiguation, WSD&#xff09;的概念及其在自然语言处理中的应用之一。词义消歧是确定一个词在特定语境下使用时所指的具体含义。 在提到的例子中&#xff0c;“Do you believe in clubs for young people?…

java跨平台原理,jdk/jre/jvm之间的关系

1 java基本认识 1.1 java语言 语言&#xff1a;人与人交流沟通的方式。比如&#xff0c;你好、hello等。 计算机语言&#xff1a;人与计算机之间进行信息交流的一种特殊方式。比如&#xff0c;Java语言、C语言、C等。 1.2 java的来源 Java 是由 Sun Microsystems 公司于 1…

状态机高阶讲解-03

402 00:17:30,860 --> 00:17:34,610 那首先要说在前面的&#xff0c;就是说 403 00:17:36,590 --> 00:17:39,770 这个状态机实际上已经是一种 404 00:17:42,060 --> 00:17:45,320 描述行为上的差别了 405 00:17:45,820 --> 00:17:47,860 就是说&#xff0c;实际…

SpringBoot中MD5使用

SpringBoot中MD5使用 新建md5类 public final class MD5 {public static String encrypt(String strSrc) {try {char[] hexChars {0, 1, 2, 3, 4, 5, 6, 7, 8,9, a, b, c, d, e, f};byte[] bytes strSrc.getBytes();MessageDigest md MessageDigest.getInstance("MD5…

组态软件基础知识

一、组态软件基础知识 1、概述 &#xff08;1&#xff09;、组态软件概念与产生背景 “组态”的概念是伴随着集散型控制系统&#xff08;Distributed Control System简称DCS&#xff09;的出现才开始被广大的生产过程自动化技术人员所熟知的。在工业控制技术的不断发展和应用…

HR人才测评,如何测评候选人的心理素质?

心理素质&#xff0c;指的是处于压力之下&#xff0c;其解决问题的能力、团队协作能力&#xff0c;事务处理的效率等是否保持稳定和高效。心理素质决定了员工在岗位上的适应能力&#xff0c;也是发展潜力的基础。 对于企业来说&#xff0c;心理素质好的员工&#xff0c;不仅是…

哪些泛域名ssl证书一年送一月

泛域名SSL数字证书&#xff0c;也称之为通配符SSL证书&#xff0c;是数字证书中比较特殊的产品。与传统的单域名SSL证书不同&#xff0c;泛域名SSL证书能够同时保护多个域名站点&#xff0c;只对域名站点的类型有限制——只能保护主域名以及主域名下的所有子域名站点。今天就随…

数据安全与销毁:数据销毁实践指南

数据销毁处理 为了满足合规要求及组织机构本身的业务发展需求&#xff0c;组织机构需要对数据进行销毁处理。因为数据销毁处理要求针对数据的内容进行清除和净化&#xff0c;以确保攻击者无法通过存储介质中的数据内容进行恶意恢复&#xff0c;从而造成严重的敏感信息泄露问题。…

【C++从0到王者】第五十二站:跳表

文章目录 一、什么是跳表二、skiplist的效率三、skiplist的实现 一、什么是跳表 skiplist本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样的&#xff0c;可以作为key或者key/value的查找模型。 skiplist&#xff0c;…

V1.2基站设置IP及设置基站连接服务器

基站状态指示灯 基站正常连接上服务器&#xff0c;基站指示灯如下&#xff0c;第一个灯是电源指示灯常亮&#xff1b;第二个灯为运行指示灯&#xff0c;程序正常运行第二个灯一直闪烁&#xff1b;第三个灯为为网络指示灯&#xff0c;网络连接正常会常亮&#xff0c;网络不通或…

专注于 DeFi 的 EVM 兼容 L1项目Berachain加入Hack.Summit()2024区块链开发者大会的联合主办之一

在激动人心的区块链领域&#xff0c;我们很荣幸的宣布Berachain已成Hack.Summit()2024区块链开发者大会的联合主办方之一。这一盛会将汇聚全球顶尖的开发者、投资者和创新者&#xff0c;共同探讨区块链技术的未来发展。 作为比特币生态的领军项目&#xff0c;Berachain始终积极…

AI入门笔记(四)

深度学习是人工智能的一种实现方法。本文我将学习到的关于深度学习的代表卷积神经网络的数学结构分享给大家。 深度学习是重叠了很多层的隐藏层&#xff08;中间层&#xff09;的神经网络。我们以一个例题为例。 建立一个卷积神经网络&#xff0c;用来识别通过 66 像素的图像读…

LINE社群:为您的跨境出海业务带来更多流量

LINE 社群就是一个大型的公开聊天室&#xff0c;通过LINE社群不需要将对方添加为好友就可以聊天。它主要是以「兴趣」作为区分&#xff0c;所以商家可以在社群中找到不少潜在客户。尤其是面向台湾、日本、泰国这些地区的商家&#xff0c;LINE在这些地区的普及度很高&#xff0c…

云流化技术方案的优势

数字化的时代&#xff0c;许多新兴的技术都逐渐走进人们的视野&#xff0c;云流化作为一种新兴的技术在各个领域发挥着越来越重要的作用&#xff0c;也为我们带来了方便快捷的使用体验&#xff0c;尤其是在虚拟仿真和数字孪生领域&#xff0c;但是有的人可能听到这个词会比较陌…

RT-Thread软件+华大开发板 配置USART+MSH控制台

Step1: 打开IDE 并新建一个工程文件 step2: 在工程文件名右键 -> 点击串口->配置项 Step3: 点击 “硬件” -> “Enable UART” -> "Enable UART7" Step4: 点击“组件” -> “MSH: command shell” Step5: 保存整个工程&#xff0c; 并打开工…

使用 Docker 部署 Next Terminal 轻量级堡垒机

1&#xff09;Next Terminal 介绍 官网&#xff1a;https://next-terminal.typesafe.cn/ GitHub&#xff1a;https://github.com/dushixiang/next-terminal 想必经常玩服务器的都了解过 堡垒机&#xff0c;类似于跳板机&#xff0c;但与跳板机的侧重点不同。堡垒机的主要功能是…

java poi-tl 使用 模板 生成文档

1.引入依赖 <!--导出doc模板工具--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.6</version></dependency> 2.编码 /*** 导出doc文件* param id* return*/GetMapping(…

快乐生活,快乐分享,5款实用的小软件推荐

​ 分享是一种神奇的东西&#xff0c;它使快乐增大&#xff0c;它使悲伤减小&#xff0c;坚持分享一些好用的软件给大家&#xff0c;今天继续为大家带来五款好用的小软件。 1.数字笔记应用——OneNote ​ OneNote是微软推出的数字笔记应用&#xff0c;提供了一个集中的地方来…

泡菜生产加工厂污水处理需要哪些工艺设备

泡菜生产加工厂污水处理是一个重要的环境问题&#xff0c;需要采用一系列工艺设备来有效处理污水并降低对环境的影响。以下是一些常见的工艺设备&#xff0c;可以在泡菜生产加工厂中使用&#xff1a; 1. 沉淀池&#xff1a;沉淀池是最常用的工艺设备之一&#xff0c;其主要作用…

产品说明文件的二维码怎么做?扫码看文件在线生成技巧

现在很多企业会把产品说明书的文件做成二维码后&#xff0c;印刷到产品包装或者宣传展板上&#xff0c;让其他人通过扫码来查看说明&#xff0c;有效的提高了用户体验。那么文件二维码制作的方法和步骤可能有很多小伙伴都不太清楚&#xff0c;那么今天小编通过本篇文章来给大家…