个人项目:论文查重
| 这个作业属于哪个课程 | 地址 |
|---|---|
| 这个作业要求在哪里 | 要求 |
| 这个作业的目标 | 论文查重 |
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 15 | 30 |
| Estimate | 估计这个任务需要多少时间 | 30 | 50 |
| Development | 开发 | 500 | 150 |
| Analysis | 需求分析 (包括学习新技术) | 200 | 450 |
| Design Spec | 生成设计文档 | 40 | 45 |
| Design Review | 设计复审 | 55 | 50 |
| Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 35 |
| Design | 具体设计 | 20 | 40 |
| Coding | 具体编码 | 240 | 280 |
| Code Review | 代码复审 | 20 | 30 |
| Test | 测试(自我测试,修改代码,提交修改) | 250 | 290 |
| Reporting | 报告 | 90 | 120 |
| Test Repor | 测试报告 | 40 | 50 |
| Size Measurement | 计算工作量 | 40 | 60 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 40 | 45 |
| 合计 | 1360 | 1635 |
算法及流程
- 读取命令行参数
使用argc和argv获取命令行参数。
检查参数数量是否正确。
- 读取文件内容
使用std::ifstream读取文件内容。
检查文件是否成功打开。
- 预处理文本
使用正则表达式去除标点符号。
将文本转换为小写。
-
统计词频
使用std::map存储每个词的频率。 -
计算余弦相似度
计算点积和模长。
使用公式计算余弦相似度。
- 输出结果
使用std::ofstream将结果写入文件。
使用std::cout将结果输出到控制台。
关键算法的代码
- 余弦相似度计算的C++代码:
`
#include <map>
#include <string>
#include <cmath>
double cosine_similarity(const std::map<std::string, int> &freq1, const std::map<std::string, int> &freq2) {
double dot_product = 0.0; // 点积
double magnitude1 = 0.0; // 向量1的模长
double magnitude2 = 0.0; // 向量2的模长
// 计算点积和向量1的模长
for (const auto &pair : freq1) {
const std::string &word = pair.first;
int count1 = pair.second;
int count2 = freq2.count(word) ? freq2.at(word) : 0; // 如果word在freq2中存在,则获取其频率;否则为0
dot_product += count1 * count2;
magnitude1 += std::pow(count1, 2);
}
// 计算向量2的模长
for (const auto &pair : freq2) {
magnitude2 += std::pow(pair.second, 2);
}
// 计算模长的平方根
magnitude1 = std::sqrt(magnitude1);
magnitude2 = std::sqrt(magnitude2);
// 避免除零错误
if (magnitude1 == 0 || magnitude2 == 0) {
return 0.0;
}
// 返回余弦相似度
return dot_product / (magnitude1 * magnitude2);
}`
性能分析

异常处理
- 命令行参数检查
if (argc != 4) { std::cerr << "Usage: " << argv[0] << " <original_file> <copied_file> <output_file>\n"; return 1; }
- 文件打开失败处理
原文文件打开失败:
std::ifstream original_file(argv[1]); if (!original_file) { std::cerr << "Failed to open original file: " << argv[1] << "\n"; return 1; }
抄袭版文件打开失败:
std::ifstream copied_file(argv[2]); if (!copied_file) { std::cerr << "Failed to open copied file: " << argv[2] << "\n"; original_file.close(); // 关闭已打开的原文文件 return 1; }
输出文件打开失败:
std::ofstream output_file(argv[3]); if (!output_file) { std::cerr << "Failed to open output file: " << argv[3] << "\n"; return 1; }
*除零错误处理:
if (magnitude1 == 0 || magnitude2 == 0) { return 0.0; }
浙公网安备 33010602011771号