这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-12 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13220 |
这个作业的目标 | 学会论文查重算法,学会使用git等操作 |
GitHub地址:https://github.com/wenzb456123/3122004790
环境:idea2024,JDK1.9
一、PSP表格:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 85 |
Estimate | 估计这个任务需要多少时间 | 65 | 60 |
Development | 开发 | 120 | 240 |
Analysis | 需求分析 (包括学习新技术) | 60 | 30 |
Design Spec | 生成设计文档 | 55 | 85 |
Design Review | 设计复审 | 100 | 100 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 35 | 35 |
Design | 具体设计 | 150 | 300 |
Coding | 具体编码 | 210 | 480 |
Code Review | 代码复审 | 90 | 70 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 30 |
Reporting | 报告 | 120 | 80 |
Test Repor | 测试报告 | 120 | 100 |
Size Measurement | 计算工作量 | 10 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 60 |
合计 | 1225 | 1685 |
二、算法模块接口的设计和实现过程:
1、calculateLongestCommonSubsequence(String originalFile, String plagiarizedFile)//计算最长公共子序列
2、calculateEditDistance(String originalFile, String plagiarizedFile)//计算编辑距离
3、readFile(String filePath)//将文件内容读取到字符串
4、writeResult(String outputFile, double similarity, String originalFile, String plagiarizedFile)//将计算结果和时间记录到result文件当中
5、getCurrentDate()//获取当前的时间
6、main(String[] args)//主函数
设计参数:
设计以及结果:
部分代码:
//最长公共子序列
private static double calculateLongestCommonSubsequence(String originalFile, String plagiarizedFile) throws FileNotFoundException {
String text1 = readFile(originalFile);
String text2 = readFile(plagiarizedFile);
int[] dp = new int[text2.length() + 1];
for (int i = 1; i <= text1.length(); i++) {
// 存储前一行的dp[j]的值以供后续使用
int prev = dp[0];
// 初始化当前行的dp[0]
dp[0] = 0;
for (int j = 1; j <= text2.length(); j++) {
// 存储当前行的dp[j]的值以供后续使用
int temp = dp[j];
// 如果当前位置的字符匹配
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
// 更新dp[j]为左上角的值加1
dp[j] = prev + 1;
} else {
// 否则,取前一行或前一列的较大值
dp[j] = Math.max(dp[j], dp[j - 1]);
}
// 更新prev为当前行的dp[j]的值,供下次迭代使用
prev = temp;
}
}
// 返回最长公共子序列长度除以两个字符串长度的最大值
return (double) dp[text2.length()] / Math.max(text1.length(), text2.length());
}
设计:
通过读取两个文件的内容,计算最长公共子序列和距离,进而计算两个文本的相似度,最后将结果写入到指定文件。
三、计算模块接口部分性能的改进:
1、概览
2、内存:
四、计算模块部分单元测试展示:
部分代码:
//最长公共子序列
private static double calculateLongestCommonSubsequence(String originalFile, String plagiarizedFile) throws FileNotFoundException {
String text1 = readFile(originalFile);
String text2 = readFile(plagiarizedFile);
int[] dp = new int[text2.length() + 1];
for (int i = 1; i <= text1.length(); i++) {
// 存储前一行的dp[j]的值以供后续使用
int prev = dp[0];
// 初始化当前行的dp[0]
dp[0] = 0;
for (int j = 1; j <= text2.length(); j++) {
// 存储当前行的dp[j]的值以供后续使用
int temp = dp[j];
// 如果当前位置的字符匹配
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
// 更新dp[j]为左上角的值加1
dp[j] = prev + 1;
} else {
// 否则,取前一行或前一列的较大值
dp[j] = Math.max(dp[j], dp[j - 1]);
}
// 更新prev为当前行的dp[j]的值,供下次迭代使用
prev = temp;
}
}
// 返回最长公共子序列长度除以两个字符串长度的最大值
return (double) dp[text2.length()] / Math.max(text1.length(), text2.length());
}
//编辑距离
private static double calculateEditDistance(String originalFile, String plagiarizedFile) throws FileNotFoundException {
String text1 = readFile(originalFile);
String text2 = readFile(plagiarizedFile);
int[] dp = new int[text2.length() + 1];
for (int j = 0; j <= text2.length(); j++) {
dp[j] = j;
}
for (int i = 1; i <= text1.length(); i++) {
int prev = dp[0];
dp[0] = i;
for (int j = 1; j <= text2.length(); j++) {
int temp = dp[j];
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
dp[j] = prev;
} else {
dp[j] = 1 + Math.min(prev, Math.min(dp[j], dp[j - 1]));
}
prev = temp;
}
}
return 1 - (double) dp[text2.length()] / Math.max(text1.length(), text2.length());
}
五、计算模块部分异常说明:
参数输入错误,或者参数输入数量不等于3