软工作业2--个人项目:论文查重
软件工程作业-02
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 第一次个人编程作业--论文查重 |
这个作业的目标 | 1. 学习对工程文件的性能分析和内存分析 2. 学习对工程进行单元测试 3. 学习PSP表格的制作 |
Github链接 | 作业github链接 |
一、项目概述
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
- 从命令行参数给出:论文原文的文件的绝对路径。
- 从命令行参数给出:抄袭版论文的文件的绝对路径。
- 从命令行参数给出:输出的答案文件的绝对路径。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) |
---|---|---|
Planning | 计划 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 570 |
Development | 开发 | 515 |
· Analysis | · 需求分析 (包括学习新技术) | 30 |
· Design Spec | · 生成设计文档 | 40 |
· Design Review | · 设计复审 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 15 |
· Design | · 具体设计 | 30 |
· Coding | · 具体编码 | 300 |
· Code Review | · 代码复审 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 |
Reporting | 报告 | 55 |
· Test Repor | · 测试报告 | 30 |
· Size Measurement | · 计算工作量 | 15 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 |
· 合计 | 590 |
三、程序设计流程图
四、程序结构
五、算法分析
余弦相似度是一种常用于计算文本相似度的方法,它可以用于比较两个文本文档或字符串之间的相似程度。该方法将文本视为向量,并计算它们之间的夹角。夹角越小,相似度越高。
以下是计算文本相似度的一般步骤,使用余弦相似度:
- 文本预处理:首先,对要比较的文本进行预处理,包括去除停用词、标点符号,将文本转为小写字母等。这有助于提取文本的关键信息。
- 特征提取:将文本转化为向量表示。常见的方法包括词袋模型(Bag of Words,BoW)、词嵌入(Word Embeddings)如Word2Vec、TF-IDF(Term Frequency-Inverse Document Frequency)等。这些方法将文本中的词语映射到向量空间。
- 计算余弦相似度:对于两个文本的向量表示,计算它们的余弦相似度。余弦相似度公式如下:
余弦相似度 = (A · B) / (|A| * |B|)
其中,A和B分别是两个文本的向量表示,|A|和|B|分别是它们的模长(向量的长度),而A·B是它们的点积(向量之间的内积)。 - 分数:余弦相似度计算后得到的值在 -1 到 1 之间,值越接近1表示文本越相似,越接近-1表示文本越不相似,0表示完全不相似。
六、性能分析
七、测试结果
八、PSP表格(完成后)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 570 | 700 |
Development | 开发 | 515 | 630 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 40 |
· Design Spec | · 生成设计文档 | 40 | 50 |
· Design Review | · 设计复审 | 10 | 15 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 15 | 30 |
· Design | · 具体设计 | 30 | 30 |
· Coding | · 具体编码 | 300 | 360 |
· Code Review | · 代码复审 | 30 | 45 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 55 | 70 |
· Test Repor | · 测试报告 | 30 | 45 |
· Size Measurement | · 计算工作量 | 15 | 15 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 10 |
· 合计 | 590 | 720 |
附录
主要代码
public class SimilarityMain {
public LinkedHashMap<Character, int[]> vectorMap = new LinkedHashMap<Character, int[]>();
int[] tempArray = null;
public SimilarityMain(String string1, String string2) {
for (Character character1 : string1.toCharArray()) {
if (vectorMap.containsKey(character1)) {
vectorMap.get(character1)[0]++;
} else {
tempArray = new int[2];
tempArray[0] = 1;
tempArray[1] = 0;
vectorMap.put(character1, tempArray);
}
}
for (Character character2 : string2.toCharArray()) {
if (vectorMap.containsKey(character2)) {
vectorMap.get(character2)[1]++;
} else {
tempArray = new int[2];
tempArray[0] = 0;
tempArray[1] = 1;
vectorMap.put(character2, tempArray);
}
}
}
// 求余弦相似度
public double sim() {
double result = 0;
//cos c = a*b/(|a|*|b|)
result = pointMulti(vectorMap) / sqrtMulti(vectorMap);
return result;
}
// 计算两个向量的模的乘积的平方根
public double sqrtMulti(Map<Character, int[]> paramMap) {
double result = 0;
result = squares(paramMap);
result = Math.sqrt(result);
return result;
}
// 计算两个向量的点积(点乘法)
public double pointMulti(Map<Character, int[]> paramMap) {
double result = 0;
Set<Character> keySet = paramMap.keySet();
for (Character character : keySet) {
int temp[] = paramMap.get(character);
result += (temp[0] * temp[1]);
}
return result;
}
// 计算两个向量的平方和,用于计算模
private double squares(Map<Character, int[]> paramMap) {
double result1 = 0.00; //向量1的模
double result2 = 0.00; //向量2的模
double resultproduct = 0.00;//向量积
Set<Character> keySet = paramMap.keySet();
for (Character character : keySet) {
int temp[] = paramMap.get(character);
result1 += (temp[0] * temp[0]);
result2 += (temp[1] * temp[1]);
}
resultproduct = result1 * result2;
return resultproduct;
}
}