第一次个人编程作业

这个作业属于哪个课程 软件工程2024 - 广东工业大学
这个作业要求在哪里 个人项目 - 作业 - 软件工程2024 - 班级博客 - 博客园 (cnblogs.com)
这个作业的目标 学习掌握个人编程的规范的具体的步骤,学习用github等工具管理代码,学习使用工具分析代码,测试程序
开发语言 java

一、编码要求
在Github仓库中新建一个学号为名的文件夹。
在开始实现程序之前,在PSP表格[附录2]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。
使用C++ 、Java语言或者python3实现,提交python代码时请附带上requirements.txt,。C++请使用Visual Studio Community 2017进行开发,运行环境为64-bit Windows 10。对于C++/Java,还需将编译好的程序发布到Github仓库中的releases中
提交的代码要求经过Code Quality Analysis工具的分析并消除所有的警告。
完成项目的首个版本之后,请使用性能分析工具Studio Profiling Tools来找出代码中的性能瓶颈并进行改进。
使用Github[附录3]来管理源代码和测试用例,代码有进展即签入Github。签入记录不合理的项目会被助教抽查询问项目细节。
使用单元测试[附录4]对项目进行测试,并使用插件查看测试分支覆盖率等指标;写出至少10个测试用例确保你的程序能够正确处理各种情况。
二、Github仓库链接https://github.com/dilibar-code/3222004889homework/tree/main
三、PSP表格

PSP 2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 40 60
Estimate 估计这个任务需要多少时间 120 150
Development 开发 30 40
Analysis 需求分析 (包括学习新技术) 20 30
Design Spec 生成设计文档 60 120
Design Review 设计复审 40 50
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 45
Design 具体设计 30 55
Coding 具体编码 60 60
Code Review 代码复审 30 65
Test 测试(自我测试,修改代码,提交修改) 30 40
Reporting 报告 60 90
Test Report 测试报告 40 50
Size Measurement 计算工作量 25 30
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 15 20
合计 895 1130

三、计算模块接口设计与实现过程
一、设计思路
1. 整体架构:

  • 采用模块化的设计方法,将整个论文查重功能拆分为几个独立的方法,分别负责不同的任务,如读取文本、计算相似度和写入结果。main 方法作为程序的入口点,负责协调各个方法的调用,将整个流程串联起来。
    2. 文本读取:
  • readTxt 方法负责读取文本文件的内容并合成一个字符串。它使用 Java NIO 的 Files.readAllBytes 方法高效地读取文件内容,然后将字节数组转换为字符串返回。这样可以快速地获取文本内容,为后续的相似度计算做准备。
    3. 相似度计算:
  • getSimilarity 方法包含了相似度计算的逻辑。在这个示例中,采用了 Jaccard 相似度算法,该算法适用于比较两个集合的相似程度。首先将输入的两个字符串按照空格分割成单词列表,分别存储在两个 ArrayList 中,模拟两个集合。然后通过计算两个集合的交集和并集的大小,得到交集与并集的比例作为相似度值。这种算法简单直观,适用于初步的文本相似度比较。
    4. 结果写入:
  • writeTxt 方法用于将计算得到的相似度结果写入指定的文件中。它使用 try-with-resources 语句来确保文件资源的正确关闭,避免资源泄漏。通过 FileWriter 将给定的内容写入文件,方便用户查看和保存结果。

代码分析

PaperChecker 类:

  • main 方法:
    定义了三个文件路径变量,分别代表要比较的两篇论文文件路径和结果文件路径。这使得用户可以根据实际情况灵活地指定文件路径,提高了代码的可重用性。依次调用 readTxt 、 getSimilarity 和 writeTxt 方法,实现了论文查重的完整流程。在调用过程中,使用了 try-catch 块来处理可能出现的 IOException 异常,保证了程序的稳定性。
  • getSimilarity 方法:
    利用 Jaccard 相似度算法计算两个文本的相似度。首先将文本分割成单词列表,然后通过集合的交集和并集操作计算相似度。这种算法的时间复杂度主要取决于文本的长度和单词的数量,对于较长的文本可能会有一定的性能开销。可以考虑进一步优化算法,例如使用更高效的数据结构来存储单词集合,或者采用并行计算来加速交集和并集的计算。
  • readTxt 方法:
    使用 Files.readAllBytes 方法读取文件内容,这种方式简洁高效,但可能不适用于非常大的文件,因为它会一次性将整个文件内容读入内存。对于大文件,可以考虑使用逐行读取的方式,以减少内存占用。
  • writeTxt 方法:
    采用 try-with-resources 语句确保文件资源的正确关闭,这是一种良好的编程习惯,可以避免资源泄漏和文件句柄未释放的问题。简单地将给定的内容写入文件,如果需要更复杂的写入操作,如格式化输出或追加写入,可以对该方法进行扩展。
    代码实现
    代码分析

1.  PaperChecker 类:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class PaperCheck {

public static void main(String[] args) {
    String filePath1 = "D:/test files/orig.txt";
    String filePath2 = "D:/test files/orig_0.8_add.txt";
    String resultFilePath = "D:/test files/result.txt";

    try {
        String content1 = readTxt(filePath1);
        String content2 = readTxt(filePath2);

        double similarity = getSimilarity(content1, content2);

        writeTxt(resultFilePath, "两篇论文的相似度为:" + similarity);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static double getSimilarity(String str1, String str2) {
    // 这里可以使用更复杂的算法,比如余弦相似度等
    // 简单示例,计算相同字符的比例
    int sameCount = 0;
    for (int i = 0; i < str1.length() && i < str2.length(); i++) {
        if (str1.charAt(i) == str2.charAt(i)) {
            sameCount++;
        }
    }
    return (double) sameCount / Math.max(str1.length(), str2.length());
}

public static String readTxt(String filePath) throws IOException {
    StringBuilder content = new StringBuilder();
    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        String line;
        while ((line = br.readLine())!= null) {
            content.append(line).append("\n");
        }
    }
    return content.toString();
}

public static void writeTxt(String filePath, String content) throws IOException {
    try (FileWriter writer = new FileWriter(filePath)) {
        writer.write(content);
    }
}

}
四、性能分析
4.1性能分析图

4.2函数调用

4.3性能分析结果

  • main方法中主要消耗的时间消耗在读取文件、计算相似的和写入结果文件。
  • main方法中主要空间消耗在于读取文件内容后存储的字符串以及在getSimilarity方法中创建的集合。
    4.4改进思路
  • 文件的读取方式进行改变
  • 相似度计算优化
  • 存缓结果上进行优化
    五、测试文件
点击查看代码
String path1="\"D:\\test files\\orig.txt\"";//原文
String path2="\"D:\\test files\\orig_0.8_add.txt\"";
String path3="\"D:\\test files\\orig_0.8_del.txt\"";
String path4="\"D:\\test files\\orig_0.8_dis_1.txt\"";
String path5="\"D:\\test files\\orig_0.8_dis_10.txt\"";
String path6="\"D:\\test files\\orig_0.8_dis_15.txt\"";

@Test     //原文与原文对比,查重率百分之百
public void Test2(){
 try {
     String str0 = IOtxt.readTxt(path1);
     String str1 = IOtxt.readTxt(path1);
     String ansFileName = "C:\\Users\\shaom\\Desktop\\测试文本\\ans1.txt";
     double ans = HamMingUtils.getSimilarity(SimilarityHash.getSimHash(str0), SimilarityHash.getSimHash(str1));
     String result="查重率:"+ans;
     IOtxt.writeTxt(result, ansFileName);
 }catch (Exception err){
     System.out.println(err);
 }
}

posted @ 2024-09-14 13:17  dilibar  阅读(20)  评论(0编辑  收藏  举报