个人项目
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/homework/13136 |
这个作业的目标 | 使用算法实现论文查重,学习使用测试工具和性能分析工具,加深对PSP开发流程的认识 |
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 790 | 920 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 110 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 | 20 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 100 | 100 |
· Coding | · 具体编码 | 300 | 400 |
· Code Review | · 代码复审 | 100 | 120 |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 120 |
Reporting | 报告 | 170 | 150 |
· Test Repor | · 测试报告 | 100 | 110 |
· Size Measurement | · 计算工作量 | 20 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 50 | 30 |
· 合计 | 970 | 1080 |
1.计算模块接口的设计与实现过程
通过学习了解到可以通过比较两篇文章关键词的simhash来计算两篇文章的重复程度
程序流程如下:
因此程序应包含:
(1)读写程序,通过Java的输入输出流实现;
(2)获取文章关键词的程序,通过导入现有的hankcs包实现;
(3)获取关键词hash值的程序:getHash(),通过MD5实现;
(4)获取特征向量的程序:getSimHash();
(5)比较特征向量以及计算相似度的程序:getSimilarity();
2.计算模块接口部分的性能改进
通过性能测试工具JProfiler分析得到性能图:
可见MockHelper.runnable()函数性能占比最高,但是由于我是通过hacks对中文进行分词处理的,暂时没想到什么优化方法
3.计算模块部分单元测试展示
测试函数:getSimilarityTest()
设计思路:将两段比较相似的文本进行比较,再将两段完全一致的文本进行比较,得到两个查重率,分别为百分之85.16和百分之100,判断该程序可靠性
public void getSimilarityTest() throws possibleException {
String str1=" 一位真正丽的作家永远医只为内心写腥作,只怖有惠内陆心才会真实地告诉他,他的自辟私、他船的高尚是多迪么突出。内心让他真实地夯了解自己,一旦了育解了自己也族就了解了疯世界。很多年前碉我就明白了步这耘个粟原则,可是汲要捍涤卫这个原则必须付出艰辛协的劳动和长体时我期召的痛苦,因为内心并非时时刻刻都是敞开的,镍它昂更多的时候倒是位封闭誉起来,于是只有讹写作,不弃停焰地橇写作才能使牵内心敞开,塌才隅能使自己置身于发过现之中,就像日疗出的光芒照亮了黑荒暗,胡灵感鼻这时候才掠会突然来狈到。\n" +
"\n" +
" 长期诚以来,我的作品都数是缕源出困于和现实的购那一层紧张关系。我沉湎于坑想象之中,又被现营实垦紧紧钡控制,我明确感奉受着自我的分裂,我无法使自己变得纯粹,我曾经希望自膊己成为一位童话作家,要盯不就是一位蘑实实在喻在帛作品的拥有者,如果我能够成控为这两者中的吵任何一苑个,我想隙我内心的痛苦将会巧轻微得多,可颐是与此同时我的力垄量也会双削弱很婆多越。\n" +
"\n" +
" 鸣事实上我只乡能成蜀为现在这样的作家,绦我始刃终为内心窘的需要而写乖作,理肝智影代替不了我的写蛀作,正因为炕此,我在亢很长一速段时间蛰是一个愤怒和冷漠的作家满。\n";
String str2="一位真正的作家永远只为内心写作,只有内心才会真实地告诉他,他的自私、他的高尚是多么突出。内心让他真实地了解自己,一旦了解了自己也就了解了世界。很多年前我就明白了这个原则,可是要捍卫这个原则必须付出艰辛的劳动和长时期的痛苦,因为内心并非时时刻刻都是敞开的,它更多的时候倒是封闭起来,于是只有写作,不停地写作才能使内心敞开,才能使自己置身于发现之中,就像日出的光芒照亮了黑暗,灵感这时候才会突然来到。\n" +
"\n" +
" 长期以来,我的作品都是源出于和现实的那一层紧张关系。我沉湎于想象之中,又被现实紧紧控制,我明确感受着自我的分裂,我无法使自己变得纯粹,我曾经希望自己成为一位童话作家,要不就是一位实实在在作品的拥有者,如果我能够成为这两者中的任何一个,我想我内心的痛苦将会轻微得多,可是与此同时我的力量也会削弱很多。\n" +
"\n" +
" 事实上我只能成为现在这样的作家,我始终为内心的需要而写作,理智代替不了我的写作,正因为此,我在很长一段时间是一个愤怒和冷漠的作家。\n";
String simhash1=PaperCheck.getSimHash(str1);
String simhash2=PaperCheck.getSimHash(str2);
System.out.println(PaperCheck.getSimilarity(simhash1,simhash2));
str2=str1;
simhash1=PaperCheck.getSimHash(str1);
simhash2=PaperCheck.getSimHash(str2);
System.out.println(PaperCheck.getSimilarity(simhash1,simhash2));
}
测试函数:getSimHash()
设计思路:当文本较短时,提取的关键词有限,此时应该提示文本过短
try{
if(str.length() < 400) throw new possibleException("文本过短!");
}catch (possibleException e){
e.printStackTrace();
throw e;
}
···
}
public void getSimHash() throws possibleException {
String str=" 一位真正的作家永远只为内心写作,只有内心才会真实地告诉他,他的自私、他的高尚是多么突出。" +
"内心让他真实地了解自己,一旦了解了自己也就了解了世界。" +
"很多年前我就明白了这个原则,可是要捍卫这个原则必须付出艰辛的劳动和长时期的痛苦,因为内心并非时时刻刻都是敞开的," +
"它更多的时候倒是封闭起来,于是只有写作,不停地写作才能使内心敞开,才能使自己置身于发现之中";
System.out.println(PaperCheck.getSimHash(str));
}
4.计算模块部分异常处理说明
(1)main函数执行整个过程,如果出现异常则将异常抛出,停止写入
public static void main(String[] args) {
// 从命令行输入的路径名读取对应的文件,将文件的内容转化为对应的字符串
try {
String str0 = readTxt(args[0]);
String str1 = readTxt(args[1]);
String resultFileName = args[2];
// 由字符串得出对应的 simHash值
String simHash0 = getSimHash(str0);
String simHash1 = getSimHash(str1);
// 由 simHash值求出相似度
double similarity = getSimilarity(simHash0, simHash1);
// 把相似度写入最后的结果文件中
writeTxt(similarity, resultFileName);
}catch (Exception e){
e.printStackTrace();
}
// 退出程序
System.exit(0);
}
(2)possibleException异常,如果出现文本过短的情况,则会提示文本过短
public void getSimHash() throws possibleException {
String str=" 一位真正的作家永远只为内心写作,只有内心才会真实地告诉他,他的自私、他的高尚是多么突出。" +
"内心让他真实地了解自己,一旦了解了自己也就了解了世界。" +
"很多年前我就明白了这个原则,可是要捍卫这个原则必须付出艰辛的劳动和长时期的痛苦,因为内心并非时时刻刻都是敞开的," +
"它更多的时候倒是封闭起来,于是只有写作,不停地写作才能使内心敞开,才能使自己置身于发现之中";
System.out.println(PaperCheck.getSimHash(str));
}