203
社区成员
作业要求 | https://bbs.csdn.net/topics/608092799 |
GitHub仓库地址 | https://gitcode.net/qinchaofusu/3220004910 |
PSP2.1 | Personal Sofware Process Stages | 预计耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 25 |
Estimate | 估计这个任务要多少时间 | 10 | 13 |
Development | 开发 | 270 | 330 |
Analysis | 需求分析(包括学习新技术) | 120 | 150 |
Design Spec | 生成设计文档 | 30 | 35 |
Design Review | 设计复审 | 20 | 30 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 20 | 30 |
Design | 具体设计 | 40 | 45 |
Coding | 具体编码 | 240 | 350 |
Code Review | 代码复审 | 30 | 40 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 70 |
Reporting | 报告 | 90 | 80 |
Test Repor | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 20 | 10 |
Postmortem & Process Plan | 事后总结(并提出过程改进计划) | 20 | 15 |
合计 | 1030 | 1253 |
MainPaperCheck:main 方法所在的类
HammingUtils:计算海明距离的类
SimHashUtils:计算 SimHash 值的类
readFileString:读 txt 文件的工具类
writeFileString:写 txt 文件的工具类
1、分词,把需要判断文本分词形成这个文章的特征单词。最后形成去掉噪音词的单词序列并为每个词加上权重,我们假设权重分为5个级别(1~5)。比如:“ 美国“51区”雇员称内部有9架飞碟,曾看见灰色外星人 ” ==> 分词后为 “ 美国(4) 51区(5) 雇员(3) 称(1) 内部(2) 有(1) 9架(3) 飞碟(5) 曾(1) 看见(3) 灰色(4) 外星人(5)”,括号里是代表单词在整个句子里重要程度,数字越大越重要。
2、hash,通过hash算法把每个词变成hash值,比如“美国”通过hash算法计算为 100101,“51区”通过hash算法计算为 101011。这样我们的字符串就变成了一串串数字,还记得文章开头说过的吗,要把文章变为数字计算才能提高相似度计算性能,现在是降维过程进行时。
3、加权,通过 2步骤的hash生成结果,需要按照单词的权重形成加权数字串,比如“美国”的hash值为“100101”,通过加权计算为“4 -4 -4 4 -4 4”;“51区”的hash值为“101011”,通过加权计算为 “ 5 -5 5 -5 5 5”。
4、合并,把上面各个单词算出来的序列值累加,变成只有一个序列串。比如 “美国”的 “4 -4 -4 4 -4 4”,“51区”的 “ 5 -5 5 -5 5 5”, 把每一位进行累加, “4+5 -4+-5 -4+5 4+-5 -4+5 4+5” ==》 “9 -9 1 -1 1 9”。这里作为示例只算了两个单词的,真实计算需要把所有单词的序列串累加。
5、降维,把4步算出来的 “9 -9 1 -1 1 9” 变成 0 1 串,形成我们最终的simhash签名。 如果每一位大于0 记为 1,小于0 记为 0。最后算出结果为:“1 0 1 0 1 1”。算法
readFileString类:读取文件
writeFileString类:写入文件
包含了两个静态方法:
1、getHash:传入String,计算出它的hash值,并以字符串形式输出,(使用了MD5获得hash值)
2、getSimHash:传入String,计算出它的simHash值,并以字符串形式输出,(需要调用 getHash 方法)
主要代码如下(ps:使用了外部依赖 hankcs 包提供的接口进行分词)
public static String getHash(String str) { //这个类是为了获得hash值
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5"); // 使用了MD5
return new BigInteger(1, messageDigest.digest(str.getBytes("UTF-8"))).toString(2);
} catch (Exception e) {
System.out.println("出错了。");
return str;
}
}
public static String getSimHash(String str) {
List<String> keywordList = HanLP.extractKeyword(str, str.length());//取出所有关键词
int size = keywordList.size();
int i = 0;
int[] v = new int[128];
String simHash = "";// 储存返回的simHash值
for (String keyword : keywordList) {
String keywordHash = getHash(keyword); //取hash值
if (keywordHash.length() < 128) {
int a = 128 - keywordHash.length();
for (int j = 0; j < a; j++) {
keywordHash += "0";
}
}
for (int j = 0; j < v.length; j++) {
//加权
// 对keywordHash的每一位与'1'进行比较
if (keywordHash.charAt(j) == '1') {
//权重分10级,由词频从高到低,取权重10~0
v[j] += (10 - (i / (size / 10)));
} else {
v[j] -= (10 - (i / (size / 10)));
}
}
i++;
}
//降维
for (int j = 0; j < v.length; j++) {
// 从高位遍历到低位
if (v[j] <= 0) {
simHash += "0";
} else {
simHash += "1";
}
}
return simHash;
}
}
HammingUtils
包含了两个静态方法:
1、getHammingDistance:输入两个 simHash 值,计算出它们的海明距离 distance
for (int i = 0; i < simHash1.length(); i++) {
// 每一位进行比较
if (simHash1.charAt(i) != simHash2.charAt(i)) {
distance++;
}
}
2、getSimilarity:输入两个 simHash 值,调用 getHammingDistance 方法得出海明距离 distance,在由 distance 计算出相似度。
return 0.01 * (100 - distance * 100 / 128);
##主类模块
1.从命令行输入两个文件名
2.计算两个文件的SimHash值
3.根据SimHash值计算出相似度
4.将结果存到一个文件中
5.结束程序
分别测试了读写文件模块,HammingUtils模块和SimHashUtils模块
主要模块的部分测试代码
public static void main(String[] args) {
String[] strings = {"今天", "的", "天气", "真好", "呀"};
for (String string : strings) {
String stringHash = SimHashUtils.getHash(string);
System.out.println(stringHash.length());
System.out.println(stringHash);
}
String str0 = readFileString.readTxt("e:/orig.txt");
String str1 = readFileString.readTxt("e:/orig_0.8_add.txt");
System.out.println(SimHashUtils.getSimHash(str0));
System.out.println(SimHashUtils.getSimHash(str1));
}
结果展示
overview
方法调用情况
#六、异常处理
判断输出结果的文件路径是否存在
try {
if(file.exists()){
//判断文件是否存在,如果不存在就新建一个txt
file.createNewFile();
}
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(content.getBytes());
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
实在是登不上github网站,把代码文件传到gitcode上了