第一次编程作业
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 实现查重功能,性能分析,记录PSP表格 |
PSP预计
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 40 |
Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 400 | 500 |
Analysis | 需求分析 (包括学习新技术) | 100 | 100 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 10 | 15 |
Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 5 |
Design | 具体设计 | 40 | 50 |
Coding | 具体编码 | 300 | 200 |
Code Review | 代码复审 | 30 | 20 |
Test | 测试(自我测试,修改代码,提交修改 | 30 | 60 |
Reporting | 报告 | 90 | 150 |
Test Repor | 测试报告 | 30 | 40 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 30 |
合计 | 1210 | 1260 |
接口实现
文件读取,并按标点符号进行分句存入数组
public static String[] getdata(File f) throws IOException{
InputStream in=new FileInputStream(f);
byte[] b=new byte[in.available()];
in.read(b);
String s =new String(b,"UTF-8");
String s1 = Html2Text(s);
String temp1=s1.toString().trim().replaceAll("\\s*", "");// 临时变量, 存储s没有去除标点符号的内容(只是去除空格)
String[] after = temp1.split("[?!。,]");
return after;
}
核心算法,比较两句话,通过最少几次变换能使两句话相同,算出变换的次数,变换越少越相似
public static int minEditDistance(String word1, String word2) {
/**
* 判空,word1为空,取Word2的长度,反之,亦然
*/
if (word1.length() == 0 || word2.length() == 0) {
return word1.length() == 0 ? word2.length() : word1.length();
}
//初始化矩阵
int[][] arr = new int[word1.length() + 1][word2.length() + 1];
for (int i = 0; i <= word1.length(); i++) {
arr[i][0] = i;
}
for (int j = 0; j <= word2.length(); j++) {
arr[0][j] = j;
}
/**
* 填充矩阵
*/
for (int i = 1; i <= word1.length(); i++) {
for (int j = 1; j <= word2.length(); j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
//相等时temp为0
arr[i][j] = arr[i - 1][j - 1];
} else {
//不相等时,temp为1
int replace = arr[i - 1][j - 1] + 1;
int insert = arr[i - 1][j] + 1;![](https://img2020.cnblogs.com/blog/2148151/202009/2148151-20200924194117252-1074439984.png)
int delete = arr[i][j - 1] + 1;
int min = Math.min(replace, insert);
min = Math.min(min, delete);
arr[i][j] = min;
}
}
}
return arr[word1.length()][word2.length()];
}
通过两个for循环,比较所有的句子,得出相似句子的数量,除于原版句子的数量算出相似度,如果已经找到一个相似的句子,则要跳出内循环,不然相似的句子会非常多
float k=0;
File file1=new File("D:\\桌面\\test(1)\\test\\orig.txt");
File file2=new File("D:\\桌面\\test(1)\\test\\orig_0.8_del.txt");
String[] s1 = getdata(file1); //原版
String[] s2 = getdata(file2); //盗版
for(int i=0;i<s2.length;i++){
for(int j=0;j<s1.length;j++){
int distance = minEditDistance(s1[j], s2[i]);
if(distance<5){
k=k+1;
break;
//System.out.println(distance);
}
}
}
OutputStream out =new FileOutputStream("D:\\桌面\\test(1)\\test\\a.txt");
Float d=k/s1.length;
byte[] bytes = d.toString().getBytes();
out.write(bytes);
out.flush();
System.out.println("重复率:"+k/s1.length);
运行结果
异常处理
性能分析
类的内存占用