第一次个人编程作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13468 |
| 这个作业的目标 | <你理解的作业目标具体内容> |
PSP
| PSP2.1 | Personal Software ProcessStages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 30 | 60 |
| · Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
| Development | 开发 | 30 | 60 |
| · Analysis | · 需求分析 (包括学习新技术) | 30 | 90 |
| · Design Spec | · 生成设计文档 | 30 | 30 |
| · Design Review | · 设计复审 | 30 | 30 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
| · Design | · 具体设计 | 30 | 30 |
| · Coding | · 具体编码 | 30 | 30 |
| · Code Review | · 代码复审 | 30 | 30 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 30 | 30 |
| Reporting | 报告 | 30 | 30 |
| · Test Repor | 测试报告 | 30 | 30 |
| · Size Measurement | · 计算工作量 | 30 | 30 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
| 合计 |
文本相似度检测系统设计与分析
类设计
我将系统设计为以下三个核心类:
TextProcessor类 - 负责文本预处理
remove_punctuation(text): 去除标点符号
tokenize(text): 分词处理
normalize(text): 文本标准化
SimilarityCalculator类 - 负责相似度计算
create_vector(tokens1, tokens2): 创建词频向量
cosine_similarity(vec1, vec2): 计算余弦相似度
calculate(text1, text2): 计算整体相似度
FileHandler类 - 负责文件操作
read_file(file_path): 读取文件内容
write_result(result, output_path): 写入结果
normalize_path(path): 标准化文件路径
函数关系
文本相似度检测系统设计与分析
代码组织结构设计
类设计
我将系统设计为以下三个核心类:
TextProcessor类 - 负责文本预处理
remove_punctuation(text): 去除标点符号
tokenize(text): 分词处理
normalize(text): 文本标准化
SimilarityCalculator类 - 负责相似度计算
create_vector(tokens1, tokens2): 创建词频向量
cosine_similarity(vec1, vec2): 计算余弦相似度
calculate(text1, text2): 计算整体相似度
FileHandler类 - 负责文件操作
read_file(file_path): 读取文件内容
write_result(result, output_path): 写入结果
normalize_path(path): 标准化文件路径
函数关系
复制主程序(main)
│
├── FileHandler.read_file() → 获取原始文本
│
├── TextProcessor预处理 → 清洁分词后的文本
│
├── SimilarityCalculator计算 → 生成相似度结果
│
└── FileHandler.write_result() → 输出结果
关键函数流程图

算法关键点
1.余弦相似度计算:
将文本转换为向量空间模型
计算两个向量间的夹角余弦值
值域为[0,1],越接近1表示越相似
2.文本预处理:
标点符号去除,减少噪声
中文分词处理,使用jieba分词库
构建统一的词汇表空间
3.向量构建:
基于两篇文档的所有唯一词汇创建向量空间
统计每个词汇在各自文档中的出现频率
形成高维词频向量独到之处
4.多编码格式支持:
自动检测文件编码(UTF-8/GBK)
避免因编码问题导致的处理失败
路径规范化处理:
自动处理路径中的引号和不同操作系统分隔符
增强跨平台兼容性
5.批处理能力:
支持单文件对比和批量处理模式
便于大规模文本相似度分析
6.异常处理机制:
全面的异常捕获和处理
零向量特殊情况的处理
7.可扩展架构:
模块化设计便于添加新的相似度算法
清晰的接口设计支持功能扩展这个设计保持了原代码核心功能的同时,通过面向对象的方式提高了代码的可维护性和可扩展性,为后续添加更多相似度算法(如Jaccard相似度、编辑距离等)奠定了基础。
点击查看代码
import jieba
import numpy as np
import string
import sys
import os
def cos_dist(vec1, vec2):
"""计算余弦相似度"""
# 处理零向量情况
if np.all(vec1 == 0) or np.all(vec2 == 0):
return 0.0
dist1 = float(np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)))
return dist1
def remove_punctuation(text):
"""去除标点符号"""
translator = str.maketrans("", "", string.punctuation)
return text.translate(translator)
def preprocess_text(text):
"""预处理文本"""
# 去除标点符号
text = remove_punctuation(text)
# 分词
words = list(jieba.cut(text))
return words
def create_vector(words1, words2):
"""创建词频向量"""
# 获取所有唯一词
all_words = list(set(words1 + words2))
# 创建词频向量
vector1 = np.zeros(len(all_words))
vector2 = np.zeros(len(all_words))
# 填充词频向量
for i, word in enumerate(all_words):
vector1[i] = words1.count(word)
vector2[i] = words2.count(word)
return vector1, vector2
def normalize_path(file_path):
"""标准化文件路径,处理引号和反斜杠"""
# 去除路径两端的引号
if file_path.startswith('"') and file_path.endswith('"'):
file_path = file_path[1:-1]
# 确保路径使用正确的分隔符
file_path = os.path.normpath(file_path)
return file_path
def read_file(file_path):
"""读取文件内容"""
# 标准化路径
file_path = normalize_path(file_path)
try:
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
except UnicodeDecodeError:
# 如果UTF-8解码失败,尝试使用GBK编码
with open(file_path, 'r', encoding='gbk') as file:
return file.read()
except Exception as e:
print(f"读取文件 {file_path} 时出错: {e}")
sys.exit(1)
def write_result(similarity, output_file):
"""将结果写入文件"""
# 标准化路径
output_file = normalize_path(output_file)
try:
with open(output_file, 'w', encoding='utf-8') as file:
file.write(f"{similarity:.2f}")
except Exception as e:
print(f"写入文件 {output_file} 时出错: {e}")
sys.exit(1)
def calculate_similarity(text1, text2):
"""计算文本相似度"""
# 预处理文本
words1 = preprocess_text(text1)
words2 = preprocess_text(text2)
# 创建词频向量
vector1, vector2 = create_vector(words1, words2)
# 计算余弦相似度
similarity = cos_dist(vector1, vector2)
return similarity
def main():
"""主函数"""
# 检查命令行参数
if len(sys.argv) != 4:
print("用法: python main.py [原文文件] [抄袭版论文的文件] [答案文件]")
sys.exit(1)
# 获取文件路径
original_file = sys.argv[1]
plagiarized_file = sys.argv[2]
output_file = sys.argv[3]
# 读取文件内容
original_text = read_file(original_file)
plagiarized_text = read_file(plagiarized_file)
# 计算相似度
similarity = calculate_similarity(original_text, plagiarized_text)
# 将相似度转换为百分比
similarity_percentage = similarity * 100
# 将结果写入输出文件(保留两位小数)
write_result(similarity_percentage, output_file)
if __name__ == "__main__":
main()
<details>
<summary>点击查看代码</summary>
import os
from main import calculate_similarity, read_file, write_result
def batch_check():
# 原文文件
original_file = "orig.txt"
original_text = read_file(original_file)
# 需要对比的抄袭版本文件
plagiarized_files = [
"orig_0.8_add.txt",
"orig_0.8_del.txt",
"orig_0.8_dis_1.txt",
"orig_0.8_dis_10.txt",
"orig_0.8_dis_15.txt"
]
# 为每个抄袭版本文件计算相似度
for plag_file in plagiarized_files:
# 读取抄袭版本内容
plagiarized_text = read_file(plag_file)
# 计算相似度
similarity = calculate_similarity(original_text, plagiarized_text)
similarity_percentage = similarity * 100
# 生成结果文件名
result_file = f"result_{plag_file}"
# 写入结果
write_result(similarity_percentage, result_file)
print(f"已生成: {result_file} - 相似度: {similarity_percentage:.2f}%")
if name == "main":
batch_check()import os
from main import calculate_similarity, read_file, write_result
def batch_check():
# 原文文件
original_file = "orig.txt"
original_text = read_file(original_file)
# 需要对比的抄袭版本文件
plagiarized_files = [
"orig_0.8_add.txt",
"orig_0.8_del.txt",
"orig_0.8_dis_1.txt",
"orig_0.8_dis_10.txt",
"orig_0.8_dis_15.txt"
]
# 为每个抄袭版本文件计算相似度
for plag_file in plagiarized_files:
# 读取抄袭版本内容
plagiarized_text = read_file(plag_file)
# 计算相似度
similarity = calculate_similarity(original_text, plagiarized_text)
similarity_percentage = similarity * 100
# 生成结果文件名
result_file = f"result_{plag_file}"
# 写入结果
write_result(similarity_percentage, result_file)
print(f"已生成: {result_file} - 相似度: {similarity_percentage:.2f}%")
if name == "main":
batch_check()
</details>


浙公网安备 33010602011771号