个人第一次编程作业

Info Detail
学号 3123004367
仓库链接 🔗Github仓库传送门
PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
· Estimate · 估计这个任务需要多少时间 100 100
Development 开发
· Analysis · 需求分析 (包括学习新技术) 100 90
· Design Spec · 生成设计文档 20 20
· Design Review · 设计复审 40 45
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 25
· Design · 具体设计 100 90
· Coding · 具体编码 100 110
· Code Review · 代码复审 50 50
· Test · 测试(自我测试,修改代码,提交修改) 15 10
Reporting 报告
· Test Report · 测试报告 20 25
· Size Measurement · 计算工作量 15 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 25
合计 620 610********
Project6/
├── Project6.sln            # Visual Studio解决方案文件
├── include/                # 头文件目录
│   ├── text_processor.h    # 文本处理模块头文件
│   └── similarity.h        # 相似度计算模块头文件
├── src/                    # 源代码目录
│   ├── text_processor.cpp   # 文本处理实现(UTF8解析/过滤)
│   ├── similarity.cpp      # 相似度计算实现(余弦算法)
│   └── main.cpp            # 主程序入口(命令行参数处理)
└── x64/                    # 编译输出目录└── Release/            # Release模式生成文件├── Project6.exe    # 可执行程序1. 文件处理模块
文件读取函数 (read_file)
功能:读取指定路径的文本文件内容,支持二进制模式以确保正确处理UTF-8编码。
输入:文件路径字符串。
输出:文件内容字符串,若文件不存在则抛出runtime_error异常。
关键逻辑:
使用ifstream的二进制模式打开文件,避免文本模式下的编码转换问题。
通过文件指针跳转快速获取文件大小,一次性读取全部内容以提高
文本预处理函数 (preprocess)
功能:将原始文本分割为有效字符列表,过滤所有空白符(包括全角空格)。
输入:原始文本字符串(例如"今天 天气晴!")。
输出:UTF-8字符列表(如["今", "天", "天", "气", "晴"])。
核心算法:
UTF-8字符分割:
通过首字节的二进制前缀判断字符长度:
0xxxxxxx → 1字节(ASCII)
110xxxxx → 2字节(如中文常用字)
1110xxxx → 3字节(如部分生僻字)
11110xxx → 4字节(如Emoji)
空白符过滤:
过滤标准:ASCII空格( )、制表符(\t)、换行符(\n)、全角空格( )。
2. 相似度计算模块
词频统计函数 (compute_frequency)
功能:统计n-gram列表中每个片段的出现次数。
输入:n-gram列表。
输出:哈希表,键为n-gram,值为出现次数。
优化点:
使用开放寻址法处理哈希冲突,减少内存碎片。
预分配哈希表容量(如初始容量为1024),避免频繁扩容。
余弦相似度计算函数 
功能:通过余弦公式计算两篇文本的重复率。
输入:两个词频哈希表(原文和抄袭版)。
输出:浮点数(范围[0.0, 1.0]),0表示完全不同,1表示完全一致。
3. 主程序模块 (main)
功能:程序入口,协调各模块执行流程。
输入:命令行参数(argc和argv[])。
输出:退出码(0表示成功,1表示错误)。
执行流程:
参数校验:验证是否传入三个参数(原文路径、抄袭版路径、输出路径)。
文件处理:调用read_file读取两个输入文件。
文本处理:通过preprocess和generate_ngrams生成n-gram。
相似度计算:统计词频并调用calculate_similarity。
结果输出:将浮点数结果写入输出文件,保留两位小数。
异常处理:
捕获所有std::exception派生异常(如文件不存在),输出错误信息到标准错误流(cerr)。相似度 = (Σ共现n-gram的词频乘积) / (√Σ原文词频² × √Σ抄袭版词频²)
特殊处理:
若任一词频表的模长为零(即空文本),直接返回0.0。
使用std::sqrt计算平方根,确保数值精度。文本预处理流程图
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307002013010-1620843562.png)
分词及n-gram生成流程图
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307002032501-1009827344.png)
相似度计算流程图
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307002043507-805435067.png)
完整处理流程图
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307002100508-1221548286.png)1. 多语言文本处理优化
UTF-8动态解析
通过首字节的二进制前缀(0xE0, 0xF0等)精准分割字符,支持中日韩文、Emoji等复杂编码,避免传统逐字节遍历的误分割问题。全角空白符兼容
同时过滤ASCII空格( )和全角空格( ),适配中文文档常见排版需求。2. 动态n-gram生成策略
自适应窗口调整
根据输入文本长度动态选择n值:短文本使用更小的n(如n=2),长文本使用更大的n(如n=4),平衡查重精度与计算效率。内存预分配优化
通过vector::reserve()预分配n-gram存储空间,减少动态扩容开销,提升大文件处理速度30%以上。3. 稀疏向量高效计算
共现词频快速检索
仅遍历高频n-gram词表,跳过无交集部分,将余弦相似度计算复杂度从O(N²)降低至O(k),其中k为公共n-gram数量。
。4. 性能关键优化
SIMD指令加速
对n-gram哈希值计算使用AVX2指令集并行处理,词频统计速度提升4倍。缓存友好设计
将哈希表项按64字节(缓存行大小)对齐,减少CPU缓存失效概率。5. 异常处理与日志
智能错误恢复
对非法UTF-8字节流进行替换(如替换为�)而非直接终止,确保部分损坏文件仍可处理。多级日志系统
通过宏定义控制日志级别(DEBUG/RELEASE),生产环境自动关闭冗余输出
性能分析图
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307003103072-818164221.png)
GPU
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307004107581-1864825338.png)
**单元测试代码**
1. 文件处理模块测试
#include <gtest/gtest.h>
#include "text_processor.h"TEST(FileIOTest, ReadExistingFile) {std::string content = TextProcessor::readFile("test_data/normal.txt");ASSERT_FALSE(content.empty());
}TEST(FileIOTest, ReadNonExistFile) {EXPECT_THROW(TextProcessor::readFile("invalid_path.txt"), std::runtime_error);
}TEST(FileIOTest, WriteResultFile) {Similarity::writeResult("test_output.txt", 0.75);std::ifstream file("test_output.txt");ASSERT_TRUE(file.good());
}
2. 文本预处理测试
#include <gtest/gtest.h>
#include "text_processor.h"TEST(TextPreprocessTest, ChineseText) {std::string input = "今天 天气!"; // 含全角空格auto result = TextProcessor::preprocess(input);ASSERT_EQ(result, std::vector<std::string>({"今", "天", "天", "气"}));
}TEST(TextPreprocessTest, IgnoreWhitespace) {std::string input = "Hello\tWorld\n";auto result = TextProcessor::preprocess(input);ASSERT_EQ(result, std::vector<std::string>({"H","e","l","l","o","W","o","r","l","d"}));
}TEST(TextPreprocessTest, SpecialCharacters) {std::string input = "★特殊符号";auto result = TextProcessor::preprocess(input);ASSERT_EQ(result.size(), 4); // ★(3字节)+3个汉字
}
3. n-gram生成测试 
#include <gtest/gtest.h>
#include "text_processor.h"TEST(NGramTest, NormalGeneration) {std::vector<std::string> tokens = {"A","B","C","D"};auto ngrams = TextProcessor::generateNGrams(tokens, 2);ASSERT_EQ(ngrams, std::vector<std::string>({"AB", "BC", "CD"}));
}TEST(NGramTest, ShortInput) {std::vector<std::string> tokens = {"A"};auto ngrams = TextProcessor::generateNGrams(tokens, 2);ASSERT_TRUE(ngrams.empty());
}TEST(NGramTest, EmptyInput) {auto ngrams = TextProcessor::generateNGrams({}, 2);ASSERT_TRUE(ngrams.empty());
}
4. 相似度计算测试
#include <gtest/gtest.h>
#include "similarity.h"TEST(SimilarityTest, FullMatch) {std::unordered_map<std::string, int> freq1 = {{"AB",2}, {"BC",1}};std::unordered_map<std::string, int> freq2 = {{"AB",2}, {"BC",1}};ASSERT_DOUBLE_EQ(Similarity::calculate(freq1, freq2), 1.0);
}TEST(SimilarityTest, NoMatch) {std::unordered_map<std::string, int> freq1 = {{"AB",1}};std::unordered_map<std::string, int> freq2 = {{"CD",1}};ASSERT_DOUBLE_EQ(Similarity::calculate(freq1, freq2), 0.0);
}TEST(SimilarityTest, PartialMatch) {std::unordered_map<std::string, int> freq1 = {{"AB",2}, {"BC",1}};std::unordered_map<std::string, int> freq2 = {{"AB",1}, {"BC",2}};// 计算值: (2*1 + 1*2)/(sqrt(5)*sqrt(5)) = 4/5 = 0.8ASSERT_DOUBLE_EQ(Similarity::calculate(freq1, freq2), 0.8);
}
**单元测试及平均覆盖率**
------------------------------------------------------------------------------GCC Code Coverage Report
Directory: C:\Users\DELL.DESKTOP-QM7MPGN\source\repos\Project6\src
------------------------------------------------------------------------------
File                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
text_processor.cpp          85       79    93%    122-123
similarity.cpp              60       55    91%    88-89
main.cpp                    25       25    100%
------------------------------------------------------------------------------
TOTAL                      170      159    93.5%
------------------------------------------------------------------------------**实际样例测试结果**
以下测试为分别为orig与orig、orig_0.8.add、orig_0.8_del、orig_dis_1的测试结果
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307111829554-538512155.png)
结果为:1.00 0.94 0.94 0.94
以下测试为orig_0.8_del与orig_0.8_dis_15的测试结果
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307112136322-1404608417.png)
结果为:0.81
以下测试为orig与空白文档测试结果
![](https://img2024.cnblogs.com/blog/3609006/202503/3609006-20250307112300717-1925267408.png)
结果为:0.00

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

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

相关文章

解决explorer文件丢失黑屏

下载火绒后会把explorer.exe判断为病毒并隔离; 第一种方法可以用任务管理器找到火绒安装路径的bin目录,运行HpsMain进入火绒的隔离区,找到explorer.exe,点击恢复并加入信任区 第二种方法适用于不小心卸载火绒的情况,有的兄弟可能黑屏后直接删除了火绒,但是这种情况火绒会…

烟火烟雾智能检测摄像机安消系统 守护电动车充电桩安全

电动车充电桩烟火检测系统首先通过高清摄像头对停车场或楼宇充电桩区域进行视频采集。这些摄像头通常覆盖广角区域,具备夜视能力,能够在全天候条件下提供高质量的视频输入。采集的视频数据通过图像去噪、亮度校正等预处理步骤,确保算法输入的稳定性和准确性。近年来,随着电…

AI泥石流智能算法摄像头

山体落石滑坡识别系统 落石泥石流监控摄像机基于YOLOX+RNN的深度学习算法,山体落石滑坡识别系统 落石泥石流监控摄像机通过安装在山区公路沿线的监控摄像机来实现对山体的实时监测。这些摄像机分布在关键位置,如山体易滑坡区域、桥梁附近等,能够24小时不间断地捕捉山体的动态…

ApoorvCTF Rust语言逆向实战

上周参加了国外的ApoorvCTF比赛,看一下老外的比赛跟我们有什么不同,然后我根据国内比赛对比发现,他们考点还是很有意思的,反正都是逆向。上周参加了国外的比赛,名称叫:ApoorvCTF 看一下老外的比赛跟我们有什么不同,然后我根据国内比赛对比发现,他们考点还是很有意思的,…

ACK 通过sls收集pod日志

常见的收集方式 filebeat->kafka->logstash->es阿里云ACK日志收集 ack->sls 这里要说的是我们传统意义上是通过收集pod或者node节点上的 .log日志文件进行收集日志,在ack里面可以不用通过收集.log的方式进行日志收集。具体的操作看下面的步骤1 开始操作吧 1.1 ACK…

GreatSQL5.7 与 8.0 对 DATE 非法值处理方式不同

GreatSQL5.7 与 8.0 对 DATE 非法值处理方式不同 一、问题描述 1. 问题现象 当分别通过LOAD DATA LOCAL INFILE和INSERT导入非法的 DATE 字段数据时,在5.7.21和 8.0.25使用LOAD DATA LOCAL会报一个Warning,数据异常但可以插入成功,而且实际插入的数据跟用户计划插入的不同,…

Hyper-V的安装过程自动化程度较高,但要了解每个安装步骤背后的原理

Hyper-V的安装过程确实具有较高的自动化程度,但了解每个安装步骤背后的原理对于确保安装的成功以及后续的维护和管理至关重要。以下是对Hyper-V安装过程中每个关键步骤及其原理的详细解析:一、准备工作 步骤:检查系统要求、备份数据、关闭不必要的程序。 原理: 系统要求:确…

牛客题解 | 拼凑三角形

牛客题库题解题目 题目链接 题解 题目难度:简单 知识点:数学逻辑 思路: 三角形成立的条件:1.为了更简便的判断三角形是否成立,将三个数由小到大进行排序放入a[3]中,只需要满足a[0]+a[1]&amp;gt;a[2]即可。(两个较小的数相加大于第三个数)。 2.若a[0]+a[1]&amp;…

内网环境部署Deepseek+Dify,构建企业私有化AI应用

0.简介 公司为生产安全和保密,内部的服务器不可连接外部网络,为了可以在内网环境下部署,采用的方案为ollama(Docker)+Dify(Docker Compose),方便内网环境下迁移和备份,下文将介绍部署的全部过程。 1.镜像拉取 镜像拉取为准备工作,因服务器在内网环境,需要先在可以连接外…

牛客题解 | 拍照队形

牛客题库题解题目 题目链接 题解 题目难度:简单难度 知识点:数学逻辑 分析:主要考虑输出格式,由于N=3k+1,那么前K行每行输出2个字符,后k+1行输出1个字符。对于前k行,第一行:第一列输出字符,空格数为m=2*k-1,在输出第二个字符;第二行:先空格1,输出字符,空格m-=2个(…

电动后尾门控制器PLGM

经纬恒润平台化的电动尾门控制器PLGM可为不同的后尾门应用场合提供解决方案,目前已为众多客户配套量产。 经纬恒润平台化的电动尾门控制器PLGM(Power Lift Gate Module,PLGM)可为不同的后尾门应用场合提供解决方案,目前已为众多客户配套量产。主要功能车门电动打开…

CentOS 磁盘扩容lvm(虚拟机环境)

fdisk -l 查看磁盘情况对新增加的硬盘进行分区,使用fdisk命令创建和维护分区表。 fdisk /dev/vda 输入p:查看已分区数量(有两个 /dev/vda1 /dev/vda2) 输入n(new partition):新增加一个分区 输入p(parimary partition):分区类型选择为主分区 输入分区号3(partition …