第一部分 绪论
灵感
模拟论文查重的各种软件,使用java编写一个类似的小程序,实现较为简单的文本相似度计算和可视化。
主要功能设计
GUI设计,分词操作,匹配操作,高亮操作,相似度计算。
主要功能设计
GUI设计
使用边界型布局,主要分为三个部分。
北部为标题,南部为操作执行以及结果展示,中部为文本以及文本相关的功能按键布局。
分词操作
分词操作是其中需要考虑的最多的地方。为了使正则表达式既能对中文生效,又能对英文生效,我这里采用的是多个组去匹配得到结果。
匹配中文句子:\s*([^\sa-zA-Z?.!。?!;:——]+)\s*
匹配英文句子:\s*([a-zA-z ]+)\s*
本质上,这里还是以自然的标点符号,如逗号,句号,感叹号等等来截取下整个话,然后对整句话进行分析,这样可以应对大部分的文本匹配问题。需要强调的是,完全准确地处理文本分句(尤其是在包含复杂语法和标点符号的混合语言文本中)通常需要一个完整的自然语言处理(NLP)系统,而不是仅仅依靠正则表达式。
匹配操作
我们分词可得到的两个字符串数组arr1, arr2。将arr1和arr2中的元素彼此两两求出最长公共子串,并将所有计算结果记录下来,并且算出字符串之间的关系得分score。score的计算公式如下。
score = len(subString) / max(len(a), len(b)),其中a, b是两字符串subString是最长公共子串。
score是判断两个字符串之间相似性的评判标准,这里当 score >= STATUS 时,认为这两个字符串相似,并将相似部分高亮处理,否则认为这两个字符串无关。
最长公共子串的求法这里采用动态规划法。
时间复杂度: O(len(a) * len(b))。
空间复杂度: O(len(a) * len(b))。
高亮操作
高亮操作函数将根据匹配的结果,将符合规定的字符串在文本中高亮显示。为了区别不同语句,高亮颜色每次选择一个随机值用于区分。
相似度计算
我们基于文本2,分析文本1中的内容与文本2中的内容的相似程度,所以我们自定义文本的相似度计算公式如下。
相似度的计算公式: similarity = commonLength / totalLength。其中,
totalLength = text1中得到的所有子串的长度,即posStrings1中所有字符串的总长度。
commonLength = posStrings1和posStrings2匹配得到的所有最长子串的长度的总和。
样例测试
说明
测试的结果受到STATUS的取值的影响,STATUS的值越高,两句话十分相似才认为这两句话有关系(也就是高亮显示),反之,STATUS的值越低,两句话部分相似便认为两句话有关系。
结果展示
此处STATUS取值为0.36。
中英文混例
纯中文样例:(文本2节选自《荷塘月色》)
附录(源代码)
package TextComparison;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Highlighter;
import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TextComparison extends JFrame {
public final static double STATUS = 0.36; // [待修正的参数]