这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 软件工程第二次作业 |
这次作业的目标 | 实现论文查重程序并在gitcode仓库提交 |
其他参考文献 | ...... |
一、程序功能需求
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
二、开发环境
操作系统 | windows10 |
---|---|
集成软件 | visual studio2017 |
三、代码实现
(1)头文件
- file.h
#pragma once
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include <ctime>
using namespace std;
class file { //该类用来读取文件,并有友元函数用来实现查重功能
public:
file(char* route);
bool read_file();
friend double get_repetitive_rate(file& origin, file& origin_add);
private:
char* file_route; //保存要打开的文件路径
vector<char> file_text; //保存读取的文件内容
};
bool judge_route(char* route); //判断文件路径是否合法(即查重文件要存在)
double get_repetitive_rate(file& origin, file& origin_add)//查重算法实现
void write_ans(char * ans_route, double repetitive_rate); //在文件中写入查重结果
(2)具体函数实现文件
- realize_function.cpp
# define _CRT_SECURE_NO_WARNINGS
#include "file.h"
bool judge_route(char* route) {
ifstream check_route;
check_route.open(route);
return check_route.good();
}
file::file(char* route) {
file_route = route;
}
bool file::read_file() {
ifstream f;
f.open(file_route);
if (!f.is_open())
return false;
char c;
while (!f.eof()) {
f.get(c);
file_text.push_back(c);
}
f.close();
return true;
}
void write_ans(char* ans_route, double repetitive_rate) {
ofstream ans;
ans.open(ans_route,ios::ate);
if (ans.is_open())
ans << "查重率为:" << fixed << setprecision(2) << (repetitive_rate*100) << "%" << endl;
}
double get_repetitive_rate(file& origin, file& origin_add) {
int origin_size = origin.file_text.size();
int origin_add_size = origin_add.file_text.size();
vector<vector<int>> dp(origin_size + 1, vector<int>(origin_add_size + 1, 0));
for (int i = 1; i < origin_size + 1; i++) {
for (int j = 1; j < origin_add_size + 1; j++) {
if (origin.file_text[i - 1] == origin_add.file_text[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[origin_size][origin_add_size] / (max(origin_size, origin_add_size)*1.0);
}
(3)主函数入口文件
- main.cpp
# define _CRT_SECURE_NO_WARNINGS
#include "file.h"
int main(int argc, char* argv[]) {
clock_t start = clock(); //记录程序开始执行的时间
if (argc < 4 || !judge_route(argv[1]) || !judge_route(argv[2])) { //判断所给的文件地址是否有效,
cout << "输入的地址有误,请按以下格式运行(以空格分割):\n" <<
"main.exe 原文文件路径 抄袭版本论文文件路径 输入的答案文件路径" << endl;
return 0;
}
//文件所有,故创建文件类并读取要查重的原文件origin.txt和修改后的文件origin_add.txt
file origin(argv[1]);
file origin_add(argv[2]);
double repetitive_rate = 0.0;
if (origin.read_file() && origin_add.read_file())
repetitive_rate = get_repetitive_rate(origin, origin_add);
write_ans(argv[3], repetitive_rate);
clock_t end = clock(); //记录程序结束执行的时间
double cost = ((double)(end - start)) / CLOCKS_PER_SEC; //计算程序执行的总耗时,以秒为单位
cout << "cost time:" << cost << "s" << endl;
return 0;
}
四、测试情况
1.命令行使用情况(包含性能展示)
测试文件为10000来个字符
2.运行结果
五、PSP表格
PSP2.1 | Personal Software Process Stages | 预计耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 25 |
Estimate | 估计这个任务需要多少时间 | 90 | 120 |
Development | 开发 | 30 | 40 |
Analysis | 需求分析(包括学习新技术) | 20 | 25 |
Design Spec | 生成设计文档 | 10 | 5 |
Design Review | 设计复审 | 10 | 2 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 5 | 5 |
Design | 具体设计 | 15 | 10 |
Coding | 具体编码 | 30 | 50 |
Code review | 代码复审 | 20 | 15 |
Test | 测试(自我测试,修改代码,提交测试) | 30 | 15 |
Reporting | 报告 | 30 | 45 |
Test Report | 测试报告 | 15 | 12 |
Size Measurement | 计算工作量 | 10 | 6 |
Postmortem & Process Improvement Plan | 事后总结 | 10 | 8 |
合计 | 255 | 258 |