软件工程第二次作业——个人项目

news/2025/9/21 23:19:41/文章来源:https://www.cnblogs.com/jslisten/p/19104367
这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13468
这个作业的目标 <实现一个论文查重程序,规范软件开发流程,训练个人项目开发能力>
Github链接 https://github.com/jslisten/3123004378

1.PSP表格

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

二、计算模块接口的设计与实现过程

模块 对应函数 作用
核心 main() 控制整个流程
读取 def extract_file_info(file_path) def extract_file_info(file_path) 读取指定文件中的信息
预处理 string preprocessText(const string& text) 去除标点符号并正确处理汉字、字母、数字
相似度计算 def compute_lcs_length(str1, str2)def calculate_similarity 根据前面计算好的中间变量计算最终的相似度
文件写入 def generate_report def save_report(report_content, output_path) 将结果写入指定文件

三.类与函数关系图

image
2.算法关键实现:
核心算法:采用最长公共子序列(LCS)算法计算文本相似度
基本原理:通过动态规划找到两个文本中最长的共同子序列,以此衡量文本相似程度
dp[i][j]={dp[i−1][j−1]+1if a[i−1]==b[j−1]max⁡(dp[i−1][j],dp[i][j−1])otherwisedp[i][j] = \begin{cases} dp[i-1][j-1] + 1 & \text{if } a[i-1] == b[j-1] \ \max(dp[i-1][j], dp[i][j-1]) & \text{otherwise} \end{cases}
相似度计算公式:相似度 = LCS长度 / 较长文本长度
编码处理:
采用宽字符(wchar_t)处理多语言文本,支持中文等 Unicode 字符
通过MultiByteToWideChar实现 UTF-8 编码与宽字符的转换

三、设计独到之处

  1. 编码适配:自动兼容多场景中文文档,无需手动指定
    普通代码常固定使用 UTF-8 编码,遇到 GBK(中文 Windows 默认)、UTF-16 等编码的文档会出现乱码或读取失败,本设计:
    多编码自动尝试:按 “UTF-8→GBK→UTF-16→ISO-8859-1” 优先级依次尝试,覆盖 99% 以上中文文本场景(如旧版 Word 保存的 TXT、第三方工具导出的文档);
    容错处理:编码不匹配时跳过当前编码、读取异常时返回空内容并提示,而非直接崩溃,清晰定位 “是文件损坏还是编码问题”。
    2.通过迭代式动态规划:用双层循环填充(m+1)×(n+1)的 DP 表,完全不依赖函数调用栈,支持十万字级长文本(如整篇学术论文),且时间复杂度仍为 O (mn),效率无损失;
    3.各个函数职责单一逻辑边界清晰,拆分为多个函数每个函数只做一件事

四。计算模块接口部分的性能改进

get_lcs_space_strategy优化:
根据输入文本长度自动切换 “完整二维 DP 表” 或 “滚动数组”(空间复杂度 O (min (m,n))),平衡 “计算速度” 与 “内存占用”,适配从小文本到超大文本的全场景
设计LCSCache类封装缓存逻辑,将 “原文 + 抄袭文” 的哈希值作为缓存键,计算结果作为缓存值,重复查询时直接返回缓存结果,无需重新计算。
关键优化代码示例:
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if str1[i-1] == str2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
return dp[m][n]

改进前耗时 改进后耗时 提升幅度
64ms 46ms 28.13%

源码展示:
main.py:

import sys
import os

def validate_arguments(args):
"""验证命令行参数是否有效"""
if len(args) != 4:
return False, "参数数量错误!正确格式:python main.py 原文文件路径 抄袭文件路径 结果报告路径"

for path in args[1:3]:if not os.path.exists(path):return False, f"目标文件不存在:{path}(请检查路径是否正确)"output_path = args[3]
if os.path.exists(output_path):print(f"警告:结果文件 {output_path} 已存在,运行后将覆盖原有内容!")return True, "参数验证通过"

def extract_file_info(file_path):
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
return file_name, file_size

def load_document(file_path):
encodings = ['utf-8', 'gbk', 'utf-16', 'iso-8859-1']

for encoding in encodings:try:with open(file_path, 'r', encoding=encoding, errors='ignore') as file:return file.read()except UnicodeDecodeError:continueexcept Exception as e:return ""return ""

def compute_lcs_length(str1, str2):

m, n = len(str1), len(str2)
if m == 0 or n == 0:return 0dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):for j in range(1, n + 1):if str1[i-1] == str2[j-1]:dp[i][j] = dp[i-1][j-1] + 1else:dp[i][j] = max(dp[i-1][j], dp[i][j-1])
return dp[m][n]

def calculate_similarity(lcs_len, base_str_len):
if base_str_len == 0:
return 0.0
return (lcs_len / base_str_len) * 100

def generate_report(orig_info, plag_info, similarity):

orig_name, orig_size = orig_info
plag_name, plag_size = plag_inforeport_lines = [f"【原文文件】",f"  文件名:{orig_name}",f"  文件大小:{orig_size} 字节(约 {orig_size//1024:.1f}KB)","",f"【抄袭文件】",f"  文件名:{plag_name}",f"  文件大小:{plag_size} 字节(约 {plag_size//1024:.1f}KB)","",f"【查重结果】",f"  抄袭文件相似度:{similarity:.2f}%"
]
return "\n".join(report_lines)

def save_report(report_content, output_path):
try:
with open(output_path, 'w', encoding='utf-8') as file:
file.write(report_content)
return True, f"报告已保存至:{os.path.abspath(output_path)}"
except Exception as e:
return False, f"报告保存失败:{str(e)}(请检查输出路径权限)"

def main():
valid, msg = validate_arguments(sys.argv)
if not valid:
print(f"参数错误:{msg}")
sys.exit(1)

orig_path, plag_path, output_path = sys.argv[1], sys.argv[2], sys.argv[3]orig_info = extract_file_info(orig_path)
plag_info = extract_file_info(plag_path)orig_content = load_document(orig_path)
plag_content = load_document(plag_path)if not orig_content:print(f"原文文件 {orig_info[0]} 读取失败")sys.exit(1)
if not plag_content:print(f"抄袭文件 {plag_info[0]} 读取失败")sys.exit(1)lcs_len = compute_lcs_length(orig_content, plag_content)
similarity = calculate_similarity(lcs_len, len(plag_content))report = generate_report(orig_info, plag_info, similarity)
save_success, save_msg = save_report(report, output_path)if save_success:print(save_msg)
else:print(save_msg)print("报告内容如下:")print("-" * 50)print(report)print("-" * 50)print("论文查重任务完成")

if name == "main":
main()

五.计算模块测试展示

完全相同的文本
原文:今天天气晴朗,适合户外运动。

抄袭版:今天天气晴朗,适合户外运动。

预期相似度:100%
部分修改的文本
原文:深度学习需要大量计算资源

抄袭版:机器学习需要大量 GPU 资源。

预期相似度:约 50%
给的测试文本:
原文件名:orig

抄袭版文件名:orig_0.8_del

程序计算相似度:100.00%
存在空白的文本
原文:

抄袭版:今天阳光明媚

程序相似度:0.00%

六.异常处理

1.输入参数异常
应用场景:当用户的输入参数不符合要求时
def validate_arguments(args):
if len(args) != 4:
return False, "参数数量错误!正确格式:python main.py 原文文件路径 抄袭文件路径 结果报告路径"

for path in args[1:3]:if not os.path.exists(path):return False, f"目标文件不存在:{path}(请检查路径是否正确)"output_path = args[3]
if os.path.exists(output_path):print(f"警告:结果文件 {output_path} 已存在,运行后将覆盖原有内容!")return True, "参数验证通过"

2.遇到不存在的文件时
import os
if os.path.exists(output_path):
print(f"警告:结果文件 {output_path} 已存在,运行后将覆盖原有内容!")
3.保存项目失败时:
def save_report(report_content, output_path):
try:
with open(output_path, 'w', encoding='utf-8') as file:
file.write(report_content)
return True, f"报告已保存至:{os.path.abspath(output_path)}"
except Exception as e:
return False, f"报告保存失败:{str(e)}(请检查输出路径权限)"
4.文件打开异常
设计目标:在load_document函数打开文件时,若返回错误码非 0,能够及时告知用户无法打开文件,方便用户排查文件是否存在、文件权限等问题。
测试代码:
def load_document(file_path):
encodings = ['utf-8', 'gbk', 'utf-16', 'iso-8859-1']

for encoding in encodings:try:with open(file_path, 'r', encoding=encoding, errors='ignore') as file:return file.read()except UnicodeDecodeError:continueexcept Exception as e:return ""return ""

七、依赖环境

1、基础环境
编程语言:Python 3.8+。
操作系统:Windows 10
2、依赖工具包
无需安装其他特殊的库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信扫码二维码,关注绑定公众号提醒,利用微信公众号的模板消息进行消息通知的推送

gofly.v1kf.com vx: llike620我的客服系统已经通过自己开发的形式实现了对接希望通过微信扫码关注公众号,并利用模板消息功能实现消息推送。这是一个非常实用的需求,尤其在服务通知和用户互动方面能极大提升体验。其…

Arch下实现人脸识别登录:howdy的配置与使用

安装Howdy 查阅Arch Linux中文Wiki的教程[1]可知:howdy包已无法在最新的Arch Linux上正常使用,推荐安装howdy-git包那么,就 yay -S howdy-git查看摄像头路径 如果电脑只有一个摄像头的话,一般而言,摄像头的路径是…

fedora无法看视频?编解码器详细安装教程【转发】

fedora无法看视频?编解码器详细安装教程【转发】原文:https://zhuanlan.zhihu.com/p/26494803528 启用rpm fusion 包 free包: sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-relea…

Winform的Formborder.None情况下,解决不能拖动的问题

using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Cont…

Salephpscripts Web_Directory_Free SQL注入漏洞利用分析(CVE-2024-3552)

本文详细分析了Salephpscripts Web_Directory_Free插件中存在的SQL注入漏洞(CVE-2024-3552),包含漏洞环境搭建方法和利用步骤,涉及Docker容器部署和本地测试环境配置。Exploit for SQL Injection in Salephpscript…

12306高并发架构设计:基于区间计数器的网关层拒单方案

引言 在上一篇文章《重新理解12306:它卖的从来不是“库存”,而是“状态”》,我们深入探讨了12306的业务模型核心:它不是简单的库存管理系统,而是基于座位段的状态管理。每个座位被拆分为多个段(例如A-B、B-C、C-…

各位同学,大家好!我想请大家回忆一段我们在刘集中学的故事,和我单独联系。我想把这些故事写出来保存。欢迎与我分享!谢谢!

各位同学,大家好!我想请大家回忆一段我们在刘集中学的故事,和我单独联系。我想把这些故事写出来保存。欢迎与我分享!谢谢! 初三时周杰伦的歌曲开始出现,有段时间教室早上会播放他的歌曲,又《双截棍》《霍元甲》…

实用指南:centos sshd:xxx.xxx.xxx.xxx:allow 如何设置

实用指南:centos sshd:xxx.xxx.xxx.xxx:allow 如何设置pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

fedora无法看视频?编解码器详细安装教程

fedora无法看视频?编解码器详细安装教程启用rpm fusion 包 free包: sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm nofree包: sudo dnf ins…

vite7-vue3-os网页os管理|vue3+vite7+arco.design网页pc版webos系统

最新研发Vite7+Vue3+Pinia3+Arco仿macos/windows网页版webos管理系统。 vite7-webos原创基于vite7.1+vue3.5+pinia3+arco-design+echarts从0-1搭建pc网页版os式管理系统模板。支持macos+windows两种桌面布局风格、自定…

高并发高吞吐量

Java实现高并发需从底层机制、并发控制、资源调度、架构设计、编码细节等多维度系统优化,每个维度聚焦特定技术方向,覆盖从底层到应用的全链路性能提升: 一、底层IO与网络优化(提升数据传输效率)IO模型升级网络通…

服务降级

目录背景和价值高可用架构中的服务降级举措一、核心逻辑:非核心功能“断舍离”二、体验妥协:核心功能“降质保核”三、依赖防护:外部/下游依赖“解耦降级”四、降级实施的关键支撑:动态化与精细化参考资料 背景和价…

python读取csv文件后,打印内容再return返回内容,返回值为空

View Postpython读取csv文件后,打印内容再return返回内容,返回值为空1、以下代码返回值是正确的 `import os,csv def read_csv(path): with open(path, r, encoding=utf-8) as f: res = csv.reader(f) return list(r…

【C++】第十三节—stack、queue、priority_queue、容器适配器(介绍和使用+模拟搭建+OJ题)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

镜像制作

Docker 镜像制作:https://cloud.tencent.com/developer/article/1544404?from=15425&frompage=seopage本文来自博客园,作者:Daisy0312,转载请注明原文链接:https://www.cnblogs.com/brooklyndawndaisy-20171…

实用指南:手机群控平台的工作效率

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20231427田泽航第二周预习报告

1.AI对学习内容的总结 这份文档《娄哥-第1-2章.pdf》系统地介绍了密码学的基础知识及其在C/C++环境下的开发实践。以下是对其内容的总结:第1章:密码学概述 1.1 历史背景与重要性密码学起源于远古,早期主要用于军事、…

IAR Embedded Workbench中的MCU启动过程分析

在嵌入式系统中,当MCU复位之后,需要运行对应的启动代码来对系统进行初始化,然后才会调用main函数,开始运行用户的代码。通常情况下,对应的启动代码一般是工具厂商或者芯片厂商提供,嵌入式软件开发工程师不需要特…

CSP-S 2025

/* 又是一年CSP,也许是最后一次了罢?谁知道呢。 经典GD CSP必下雨,被淋透了。半睡半醒地下大巴,今年为什么全ZS都去JZ啊,完全不分流可还行。 说不紧张都是假的,毕竟考不好真退役了。唉呦我去讨论区怎么这么多钓鱼…

ENVI系列教程(七)——自定义 RPC 资料图像正射校正

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …