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

news/2025/9/23 20:17:20/文章来源:https://www.cnblogs.com/fpnn/p/19106423

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

------------恢复内容开始------------

一、作业信息

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13469
这个作业的目标 创建GitHub账号,建立个人博客,进行自我介绍,对软件工程提出问题,初步认识软件工程

GitHub仓库:https://github.com/fengpengGG/3123004349

二、PSP表格

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

总结:由于没怎么接触过类似的项目,所以在学习新技术和方法,比如git,性能测试,单元测试等,具体编码和测试代码阶段花了比预想长很多的时间

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

(一)关系分析

计算模块(Check.h)是文本相似度检测功能的核心,其设计需与数据读取模块(FileHandling.h)、文本预处理模块(TextPreprocess.h)协同工作,整体结构采用 “分层协作” 模式,具体组织如下:

1.核心类与函数的划分

Check 类:封装相似度计算的核心逻辑,对外提供静态接口函数,无需实例化。
核心函数:static double calculate_similarity(const vector& words1, const vector& words2)
功能:接收两个预处理后的分词结果,返回两者的相似度

2. 类之间的依赖关系

计算模块依赖其他模块的输出作为输入,具体关系如下:
FileHandling.h 模块:负责读取原始文本文件(如源文件、抄袭文件),输出原始字符串;
TextPreprocess.h 模块:接收原始字符串,进行预处理全半角转换、去标点、分词等,输出分词结果;
Check.h 模块:接收 TextPreprocess.h 输出的两个分词结果,计算并返回相似度;
最终通过 FileHandling.h 将相似度结果写入输出文件。
整体数据流向:FileHandling.read_file() → TextPreprocess.process_text() → Check.calculate_similarity() → FileHandling.write_result()。

(二)关系函数流程图

屏幕截图 2025-09-23 163856

(三)算法关键

计算模块采用 Jaccard 系数算法 作为核心,其核心思想如下:
Jaccard 系数基础:原始公式为 J(A,B)= ∣A∪B∣/∣A∩B∣
其中 A 和 B 是两个集合。
词频适配:针对文本分词结果(含重复词),将 “集合” 扩展为 “带频率的词集合”:
交集:每个词在两个文本中出现次数的最小值之和(反映共同出现的词的重叠程度);
并集:每个词在两个文本中出现次数的最大值之和(反映两个文本的总信息量);
相似度 = 交集 / 并集

(四)独到之处

边界情况全覆盖:处理 “两个文本均为空”“其中一个为空”“并集为 0” 等极端情况,避免程序崩溃或无效输出;
结果约束:通过 max(0.0, min(1.0, similarity)) 确保输出相似度严格在 0-1 区间内。
接口设计通用:输入为标准容器 vector,与任何文本预处理模块兼容,若更换分词方式,无需修改计算逻辑;
算法易替换:Check 类封装了计算逻辑,若需替换为余弦相似度等其他算法,只需修改 calculate_similarity 函数内部实现,不影响其他模块。

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

性能改进前:
屏幕截图 2025-09-22 234839
修改性能后:
屏幕截图 2025-09-22 235006
修改之后可见核心函数cpu占比降低,内核开销减少,内存使用平稳。
消耗时间:性能改进时间为2小时左右。

(一)改进思路:

从文件读写,文本预处理,相似度计算三个方面进行优化。其中文本预处理的性能需求最高。
文件读取:
模块增大缓冲区,减少调用次数。
文本预处理:
用string_view替代substr,因为substr会频繁创建临时字符串,内存开销大。
预分配vector空间
相似度计算:
用单哈希表统计词频,简化哈希操作,减少遍历开销

代码中消耗最大的函数:Textpreprocess::segment_words
是文本预处理的核心函数,负责将清洗后的原始文本拆分为词语序列。其处理对象是原始文本的每个字符,处理规模与输入文本的总字符数直接相关。

五、计算模块部分单元测试展示

#include <gtest/gtest.h>
#include <vector>
#include "Check.h"// 测试用例1:两个空文本(边界条件)
TEST(SimilarityTest, BothEmptyTexts) {vector<string> words1;vector<string> words2;double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 1.0, 0.001); // 空文本视为完全相似
}// 测试用例2:一个空文本,一个非空文本(边界条件)
TEST(SimilarityTest, OneEmptyText) {vector<string> words1 = { "苹果", "香蕉", "橙子" };vector<string> words2;double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.0, 0.001); // 空文本与非空文本相似度为0
}// 测试用例3:完全相同的文本(典型场景)
TEST(SimilarityTest, IdenticalTexts) {vector<string> words1 = { "今天", "天气", "很好", "适合", "散步" };vector<string> words2 = { "今天", "天气", "很好", "适合", "散步" };double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 1.0, 0.001); // 完全相同相似度为1
}// 测试用例4:完全不同的文本(典型场景)
TEST(SimilarityTest, TotallyDifferentTexts) {vector<string> words1 = { "计算机", "程序", "算法" };vector<string> words2 = { "苹果", "香蕉", "橙子" };double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.0, 0.001); // 无重叠词相似度为0
}// 测试用例5:部分重叠(词频相同)
TEST(SimilarityTest, PartialOverlapSameFrequency) {vector<string> words1 = { "猫", "狗", "鸟", "鱼" };vector<string> words2 = { "猫", "狗", "兔", "熊" };// 交集:"猫"、"狗" → 2;并集:"猫"、"狗"、"鸟"、"鱼"、"兔"、"熊" → 6 → 2/6≈0.333double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.333, 0.001);
}// 测试用例6:部分重叠(词频不同)
TEST(SimilarityTest, PartialOverlapDifferentFrequency) {vector<string> words1 = { "书", "书", "笔", "纸" }; // 书:2, 笔:1, 纸:1vector<string> words2 = { "书", "笔", "笔", "橡皮" }; // 书:1, 笔:2, 橡皮:1// 交集:min(2,1) + min(1,2) = 1+1=2;并集:max(2,1)+max(1,2)+max(1,0)+max(0,1)=2+2+1+1=6 → 2/6≈0.333double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.333, 0.001);
}// 测试用例7:包含重复词的文本
TEST(SimilarityTest, TextsWithDuplicateWords) {vector<string> words1 = { "重复", "重复", "重复" };vector<string> words2 = { "重复", "重复" };// 交集:min(3,2)=2;并集:max(3,2)=3 → 2/3≈0.667double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.667, 0.001);
}// 测试用例8:包含停用词(已过滤后的场景)
TEST(SimilarityTest, TextsWithStopWordsFiltered) {vector<string> words1 = { "的", "是", "重要", "的" }; // 假设停用词"的"未被过滤vector<string> words2 = { "的", "是", "关键", "的" };// 交集:"的":min(2,2)=2,"是":min(1,1)=1 → 3;并集:"的":2,"是":1,"重要":1,"关键":1 → 5 → 3/5=0.6double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.6, 0.001);
}// 测试用例9:中英文混合文本
TEST(SimilarityTest, MixedChineseEnglishTexts) {vector<string> words1 = { "hello", "世界", "python", "编程" };vector<string> words2 = { "hello", "python", "java", "世界" };// 交集:"hello"、"世界"、"python" → 3;并集:4+4-3=5 → 3/5=0.6double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.6, 0.001);
}// 测试用例10:超长文本(性能与正确性验证)
TEST(SimilarityTest, LongTexts) {vector<string> words1, words2;// 构造超长文本(各1000个词,重叠率50%)for (int i = 0; i < 1000; i++) {words1.push_back("词" + to_string(i));if (i % 2 == 0) words2.push_back("词" + to_string(i)); // 偶数索引词重叠}for (int i = 1000; i < 1500; i++) {words2.push_back("词" + to_string(i)); // 新增500个不重叠词}// 交集:500(偶数词);并集:1000 + 1500 - 500 = 2000 → 500/2000=0.25double result = Check::calculate_similarity(words1, words2);ASSERT_NEAR(result, 0.333, 0.001);
}// 自定义main函数(若不使用gtest_main.lib)
int main(int argc, char** argv) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

屏幕截图 2025-09-23 191903

思路:

1.边界场景覆盖

一个空文本,两个都是空文本

2.核心逻辑验证

完全相同文本和完全不同文本验:证算法基础正确性
部分重叠文本:验证交集和并集的计算逻辑。

3.特殊场景适配

重复词:测试算法对词频权重的处理
停用词和中英混合:验证算法对多类型文本的兼容性。

所有测试用例通过,表明calculate_similarity函数在边界条件、典型场景和特殊场景下均能返回正确结果

六、计算模块部分异常处理说明

1.无法打开文件

当指定路径的文件不存在、路径格式错误、文件被占用或无读取权限时,及时抛出异常,避免程序在未正确打开文件的情况下进行后续读写操作,防止不可预期的内存错误或逻辑异常。

读取不存在的片段:

#include <iostream>
#include "FileHandling.h"
using namespace std;int main() {string invalid_path = "C:\\nonexistent_file.txt"; // 不存在的文件路径try {string content = FileHandling::read_file(invalid_path);} catch (const runtime_error& e) {cout << "捕获异常:" << e.what() << endl;}return 0;
}

结果:
image

2.无法打开结果文件

当结果文件路径无效、无写入权限或文件被其他程序锁定时,抛出异常。防止程序在无法写入结果的情况下继续执行,确保相似度计算结果能正确保存到指定路径。

结果文件路径的目录不存:

#include <iostream>
#include "FileHandling.h"
using namespace std;int main() {string invalid_result_path = "C:\\invalid_dir\\result.txt"; // 目录不存在try {FileHandling::write_result(invalid_result_path, 0.85);} catch (const runtime_error& e) {cout << "捕获异常:" << e.what() << endl;}return 0;
}

结果:
image

3.写入结果文件失败

文件成功打开后,若写入过程中出现错误(如磁盘满、文件被突然删除),导致写入状态异常时,抛出异常。确保相似度结果能完整写入文件,避免生成空文件或不完整的结果。

写入时磁盘空间不足(可模拟为向只读文件写入)。
image

#include <iostream>
#include "FileHandling.h"
using namespace std;int main() {string read_only_path = "C:\\read_only_file.txt"; // 手动设置为只读的文件try {FileHandling::write_result(read_only_path, 0.72);} catch (const runtime_error& e) {cout << "捕获异常:" << e.what() << endl;}return 0;
}

结果:
image
------------恢复内容结束------------

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

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

相关文章

做网站下载那个数据库好wordpress开发 文档下载

6月15日&#xff0c;一年一度的大连软交会于大连市世界博览广场盛大举行。“2017企业服务创新论坛”作为软交会最重要的组成部分之一&#xff0c;本年度以“守正出新——通往基业长青的数字化选择”为主题&#xff0c;吸引到近200位企业级服务领域的企业家及高管参加。致远互联…

开封市建设教育协会网站vue反向代理天地图地址

1 说明 此篇文章针对Chrome DevTools常用功能进行调研分析。描述了每个功能点能实现的功能、应用场景和详细操作。 2 Elements 2.1 功能 检查和实时更新页面的HTML与CSS 在 Elements 面板中检查和实时编辑 DOM 树中的任何元素。在 Styles 窗格中查看和更改应用到任何选…

南京网站制作公司报价北航刘禹导师做网站

在上一节中完成了注册功能的前期准备工作&#xff0c;在这一节内容中将完成用户注册、登录功能。1.知识预览在本届中将学习到以下内容的知识如何使用wtform来渲染表单如果使用flask-mail来发送邮件2.用户注册在前端中form表单是用的比较多的东西&#xff0c;我们可以使用wtform…

公司网站运营公司排名网站源码php

查询linux的swap被什么使用了 查询centos的swap被什么进程使用了 swap内存被什么程序占用&#xff0c;什么程序使用了swap分区&#xff0c;占用swap内存的进程 查系统使用swap内存前10个进程&#xff1a; for i in $( cd /proc;ls |grep "^[0-9]"|awk $0 >10…

大庆建设局网站首页上海做一个公司网站多少钱

Lei宝啊&#xff1a;个人主页 愿所有美好与我们不期而遇 题目描述 &#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 接口&#xff1a; bool hasCycle(struct ListNode *head) 示例1&#xff1a; 示例2&#xff1a; 返回值&#xff1a; true或…

游戏网站制作做短视频网站好

QT 子窗体 最大化 复原 遇到的问题 项目中有个需求&#xff0c;主窗体中嵌套子窗体&#xff0c;需要将子窗体最大化显示和复原。 查了很多资料&#xff0c;基本上都是提到&#xff1a;QT中窗口部件QWidget成员函数showFullScreen();是用于将窗口部件全屏显示&#xff0c;但是他…

嘉兴网站建设多少钱沧州小程序开发制作

本文介绍的是在使用jsp作为模板引擎的spring-mvc项目中&#xff0c;如何利用 PDF.js实现pdf文件的预览。 1、下载 PDF.js Getting Started (mozilla.github.io) 下载解压后其中有两个目录&#xff0c;直接将这两个文件夹放到项目的web资源目录中。此时相当于把PDF.js这个项目也…

近十年 CSP-J 复赛知识点分布表

📌 说明T1:模拟题为主,难度较低,重在代码实现能力。 T2:基础算法,如排序、枚举、二分等。 T3:多为字符串处理、搜索、基础动态规划。 T4:难度最高,常考动态规划、图论、树结构等。 难度表示:★ 为入门级,★…

校园网站建设er模型网站用ai做还是ps

目录 必须理解的知识点&#xff1a; 举一个草莓的例子&#xff1a; 机器学习的三个类别&#xff1a; 监督学习&#xff1a; 无监督学习&#xff1a; 强化学习&#xff1a; 更多知识背景&#xff1a; 机器学习的诞生需求 监督学习的关键技术与实现步骤 无监督学习的关…

AT_arc181_d [ARC181D] Prefix Bubble Sort

一个比较容易观察到的性质是,这个东西等价于冒泡排序的一轮。 考虑经典结论,就是每次对于每个结点 \(i\) 会减少前面的一个逆序对,由于 \(a\) 的单调性,所以当一个数因为逆序对的情况移动会是一段连续的区间。因为…

【MySQL】使用C/C++链接mysql数据库 - 指南

【MySQL】使用C/C++链接mysql数据库 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

自己做的网站如何链接到百度浅谈电子商务网站的建设与管理

C#制作定时任务工具执行CMD命令 概要准备知识点实现原理thinkphp配置winform执行CMD命令读取ini配置文件定时任务Quartz.Net 完整代码Job.csIniFunc.csForm1.csconfig.ini简易定时任务工具雏形 概要 很多时候写接口上线后还会遇到很多修改&#xff0c;类似JAVA,C#,delphi制作的…

集团企业网站设计方案免费的ppt制作软件

高级命令 keys * 返回满足条件的所有key&#xff0c;可以模糊匹配exists 是否存在指定的keypersist 取消过期时间select 选择数据库 &#xff08;0-15&#xff0c;总共16个数据库&#xff09;move key index 将当前数据库的 key 移动到给定的数据库 db 当中randomkey 随机返回…

地产项目网站建设监理杂志网站

以共享的方式实现不同节点之间数据交互的通信模式。 参数服务器是基于服务实现的&#xff0c;包含客户端和服务器端&#xff0c;服务端节点可以存储数据&#xff0c;客户端节点可以访问服务端节点操作数据&#xff0c;这个过程虽然基于请求响应的&#xff0c;但是无需自己实现…

网站认证网店 网站建设策划书

我们将上面开发的服务提供方服务&#xff0c;部署到2个独立的节点上&#xff08;192.168.14.1和10.10.4.125&#xff09;&#xff0c;然后可以通过Dubbo管理中心查看对应服务的状况&#xff0c;如图所示&#xff1a; 上图中可以看出&#xff0c;该服务有两个独立的节点可以提供…

网站建设 维护 编程wordpress 文章广告

项目介绍 本论文系统地描绘了整个网上论坛管理系统的设计与实现&#xff0c;主要实现的功能有以下几点&#xff1a;管理员&#xff1b;首页、个人中心、用户管理、公告管理、公告类型管理、热门帖子管理、帖子分类管理、留言板管理、论坛新天地、我的收藏管理、系统管理&#…

微信公众号的微网站怎么做的怎么做p2p网站

得到一个wma或mp3文件&#xff0c;如何用最简单的方法得到它的长度信息呢&#xff1f; Delphi / Windows SDK/APIhttp://www.delphi2007.net/DelphiMultimedia/html/delphi_20061108195617169.html不需要知道歌手名专辑名等&#xff0c;只要长度即可&#xff0c;哪个指令可以做…

网站开发app小程序软件开发的环节有哪些

最近在使用 IIS 发布 PHP 网站时&#xff0c;我遇到了一个前端问题&#xff0c;即字体库文件 404 错误。这个问题的根本原因是 IIS 未能正确识别字体文件类型&#xff0c;导致浏览器在加载页面时无法正确获取所需字体资源&#xff0c;进而触发了404错误。这样的问题会导致网站页…

网站兼职做计划赚小钱视频音乐网站怎样建设

使用PPMI改进共现矩阵 共现矩阵的元素表示两个单词同时出现的次数&#xff0c;这里的次数并不具备好的性质&#xff0c;举个例子&#xff0c;有短语叫the car&#xff0c;因为the是个常用词&#xff0c;如果以两个单词同时出现的次数为衡量相关性的标准&#xff0c;与drive 相…

day002

今日完成:斗地主牌组,牌类. 明日完成:斗地主游戏程序 遇到问题:无.