java 最长公共字符算法实现文档内容字符串对比并返回差异html

java 最长公共字符算法实现文档内容字符串对比并返回差异html

gitee地址 demo地址

1. 读取docx文档

使用POI进行文档的读取

	/**
     * 获取文档内容
     * @param path 文档磁盘路径
     * @throws IOException
     */
    private StringBuilder getDocText(String path ) throws IOException {
        StringBuilder builder= new StringBuilder();
        XWPFDocument doc = new XWPFDocument(new FileInputStream(path));

        List<IBodyElement> elements = doc.getBodyElements();
        for (IBodyElement element : elements) {
            // 段落
            if (element instanceof XWPFParagraph) {
                XWPFParagraph paragraph = (XWPFParagraph) element;

                List<XWPFRun> runs = paragraph.getRuns();
                //空行用标签换行
                if (runs.size() == 0) {
                    builder.append("<br>");
                }
                for (XWPFRun run : runs) {
                    builder.append(run.text());
                }
            }// 表格
            else if (element instanceof XWPFTable) {
                XWPFTable table= (XWPFTable) element;

                // 获取每个单元格
                List<XWPFTableRow> rows = table.getRows();

                for (XWPFTableRow row : rows) {
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 一个单元格可以理解为一个word文档,单元格里也可以加段落与表格
                        List<XWPFParagraph> paragraphs = cell.getParagraphs();
                        for (XWPFParagraph paragraph : paragraphs) {
                            List<XWPFRun> runs = paragraph.getRuns();
                            //空单元格用空格代替
                            if (runs.size() == 0) {
                                builder.append(" ");
                            }
                            for (XWPFRun run : runs) {
                                builder.append(run.text()+" ");
                            }
                        }
                    }
                    //每行加个换行标签
                    builder.append("<br>");
                }
            }
        }
        
        return builder;
        
    }


2. 查找最长公共子串

该方法引用自:Java算法——求出两个字符串的最长公共字符串 - 春秋阕 - 博客园 (cnblogs.com)

    /**
     * 查找最长公共字符算法
     * @param str1
     * @param str2
     * @return
     */
    private StringBuilder maxUtil2(String str1, String str2) {
        //把字符串转成字符数组
        char[] arr1 = str1.toCharArray();
        char[] arr2 = str2.toCharArray();
        // 把两个字符串分别以行和列组成一个二维矩阵
        int[][] temp = new int[arr1.length][arr2.length];
        // 存储最长公共子串长度
        int length = 0;
        //start表明最长公共子串的起始点,end表明最长公共子串的终止点
        int end = 0;
        int start = 0;
        初始化二维矩阵中的第一行
        for (int i = 0; i < arr2.length; i++) {
            temp[0][i] = (arr1[0] == arr2[i]) ? 1 : 0;
        }
        //初始化二维矩阵中的第一列
        for (int j = 0; j < arr1.length; j++) {
            temp[j][0] = (arr2[0] == arr1[j]) ? 1 : 0;
        }
        //嵌套for循环:比较二维矩阵中每个点对应行列字符中否相等,相等的话值设置为1,否则设置为0
        for (int i = 1; i < arr1.length; i++) {
            for (int j = 1; j < arr2.length; j++) {
                if (arr1[i] == arr2[j]) {
                    temp[i][j] = temp[i - 1][j - 1] + 1;

                    if (temp[i][j] > length) {
                        length = temp[i][j];
                        end = j;
                    }
                } else
                    temp[i][j] = 0;

            }
        }
        //求出最长公共子串的起始点
        start=end-length+1;
        StringBuilder sb=new StringBuilder();
        //通过查找出值为1的最长对角线就能找到最长公共子串
        for (int j = start; j < end+1; j++) {
            sb.append(arr2[j]);
        }

        return sb;
    }

3. 代码实现

@Data
@AllArgsConstructor
public class DiffObject {
    /**
     * 公共子串
     */
    private String name;
    /**
     * 起始位置
     */
    private Integer index;
}

调用方法代码实现

public static void main(String[] args) {

        //返回新旧文本的html的map对象
        HashMap<String, String> map = new HashMap<String, String>();
        
        //获取文件保存路径
        String oldUrl="C:/Users/12855/Desktop/1.docx";
        String newUrl="C:/Users/12855/Desktop/2.docx";


        //原始文件内容
        StringBuilder oldText = null;
        //最新文件内容
        StringBuilder newText = null;

        try {
            //获取文档内容
            oldText= getDocText(oldUrl);

            newText= getDocText(newUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }


        // 随机生成字符串
        String strOne = oldText.toString();
        String strTwo = newText.toString();

        //遍历查询到的文档名字
        ArrayList<DiffObject> demotes = new ArrayList<DiffObject>();

        while (true) {
            //获取最长公共子串
            String same = maxUtil2(strOne, strTwo).toString();

            if (same.length() <= 0) {
                break;
            }

            demotes.add(new DiffObject(same,strTwo.indexOf(same)));

            strOne= strOne.replace(same,"-");
            strTwo= strTwo.replace(same,"*");

        }

        String div="<span style=\"background-color: yellow\">"+newText.toString()+"</span>";

        for (DiffObject demote : demotes) {
            div= div.replace(demote.getName(),"<span style=\"background-color: white\">"+demote.getName()+"</span>");
        }

        map.put("oldHtml",oldText.toString());
        map.put("newHtml",div);

        System.out.println(map.get("oldHtml"));
        System.out.println(map.get("newHtml"));
    }

4. 测试文件

1.docx

根据气象部门的预报,河北中部、四川盆地西部、贵州西部、湖北中部和东南部、湖南北部、江苏中部、江西中部等地部分地区有大雾。
而内蒙古东北部、黑龙江西北部、新疆南疆西部、西藏大部、青海南部等地部分地区有小到中雪或雨夹雪。下雪天气主要分布在西部高寒地区,还有就是零星分布在北方和东北地区,对于全国影响不大。而下雨地区也是在西南地区,如西藏东南部、四川盆地西部、贵州中西部、云南东部等地有小雨。
标题1	标题2	标题3	标题4	标题5
而内蒙	北	江西	南疆	藏大
星分	东北	全国影	雨	州中
有小	零星	东北	区	西中

2.docx

根据气象部门的预报,河北中部、四川方和西部、贵州西部、湖北中部和东南部、湖南北部、江苏中部、江西中部等地部分地区有大雾。
而内蒙得到部、黑龙江西北部、新疆西部、西藏大部、青海间距地部分地方和小到中雪或雨夹雪。下雪天气主要分布间距高寒地区,还有就是零星分布行方和东北地区,对2更方和影响不大。而44下雨地区也是在西南地区,如东南部、四川5u盆地西部、贵州中西部、云南东方和地有小雨。
标题1	标题2	标题3	标题4	标题5
而内蒙	北	江西	南疆	藏大
星分	东中雪或北	对于全国	雨天	零星
而内蒙	零星	东北江西	藏大	西中

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- import CSS -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
  <div id="app">
    <el-row :gutter="24">
        <el-col :span="12"><div class="grid-content bg-purple" style="font-size: 18px">
          最新版本:
        </div></el-col>
        <el-col :span="12"><div class="grid-content bg-purple" style="font-size: 18px">
          历史版本:
        </div></el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="12"><div class="grid-content bg-purple">
          <div style="border: 1px #8EB9B9 solid; margin: 20px 20px 20px 20px;padding: 20px 20px 20px 20px;overflow-y:scroll; height: 600px"  v-html="oldHtml"></div>
        </div></el-col>
        <el-col :span="12"><div class="grid-content bg-purple">
          <div style="border: 1px #8EB9B9 solid; margin: 20px 20px 20px 20px;padding: 20px 20px 20px 20px;overflow-y:scroll; height: 600px" v-html="newHtml"></div>
        </div></el-col>
      </el-row>
  </div>
</body>
  <!-- import Vue before Element -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- import JavaScript -->
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: function() {
        return { 
			oldHtml:'根据气象部门的预报,河北中部、四川盆地西部、贵州西部、湖北中部和东南部、湖南北部、江苏中部、江西中部等地部分地区有大雾。而内蒙古东北部、黑龙江西北部、新疆南疆西部、西藏大部、青海南部等地部分地区有小到中雪或雨夹雪。下雪天气主要分布在西部高寒地区,还有就是零星分布在北方和东北地区,对于全国影响不大。而下雨地区也是在西南地区,如西藏东南部、四川盆地西部、贵州中西部、云南东部等地有小雨。标题1 标题 2 标题 3 标题 4 标题 5 <br>而内蒙 北 江西 南疆 藏大 <br>星分 东北 全国影 雨 州中 <br>有小 零星 东北 区 西中 <br><br>',
			newHtml:'<span style="background-color: yellow"><span style="background-color: white">根据气象部门的预报,河北<span style="background-color: white">中</span>部、四川</span>方和<span style="background-color: white"><span style="background-color: white">西</span>部、贵州<span style="background-color: white">西</span>部、湖北<span style="background-color: white">中</span>部和东南部、湖南北部、江苏<span style="background-color: white">中</span>部、江<span style="background-color: white">西</span><span style="background-color: white">中</span>部等<span style="background-color: white">地部分地</span>区有大雾。而内蒙</span>得到<span style="background-color: white">部、黑龙江<span style="background-color: white">西</span>北部、新疆</span><span style="background-color: white"><span style="background-color: white">西</span>部、<span style="background-color: white">西</span><span style="background-color: white">藏</span>大部、青海</span>间距<span style="background-color: white">地部分地</span>方和<span style="background-color: white">小到<span style="background-color: white">中</span>雪或雨夹雪。下雪天气主要分布</span>间距<span style="background-color: white">高寒地区,还有就是零星分布</span>行<span style="background-color: white">方和东北地区,对</span>2更方和<span style="background-color: white">影响不大。而</span>44<span style="background-color: white">下雨地区也是在<span style="background-color: white">西</span>南地区,如</span><span style="background-color: white">东南部、四川</span>5u<span style="background-color: white">盆地<span style="background-color: white">西</span>部、贵州<span style="background-color: white">中</span><span style="background-color: white">西</span>部、云南东</span>方和<span style="background-color: white">地有小雨。标题1 标题 2 标题 3 标题 4 标题 5<span style="background-color: white"> <br></span>而内蒙 <span style="background-color: white">北 </span>江<span style="background-color: white">西</span> 南疆 <span style="background-color: white">藏</span>大<span style="background-color: white"> <br></span>星分 东</span> <span style="background-color: white">中</span>雪或 <span style="background-color: white">北 </span>对<span style="background-color: white">于全国</span><span style="background-color: white"> 雨 </span>天 零星<span style="background-color: white"> <br></span>而内蒙<span style="background-color: white"> 零星 东<span style="background-color: white">北 </span></span>江<span style="background-color: white">西</span> <span style="background-color: white">藏</span>大<span style="background-color: white"> <span style="background-color: white">西</span><span style="background-color: white">中</span><span style="background-color: white"> <br></span><br></span></span>'
		}
      }
    })
  </script>
</html>

5. 演示效果

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值