软件工程第一次编程作业

这个作业属于哪个课程https://bbs.csdn.net/forums/gdut-ryuezh
这个作业要求在哪里https://bbs.csdn.net/topics/608092799
这个作业的目标1. 学习对工程文件的性能分析和内存分析;2. 学习对工程进行单元测试;3. 学习PSP表格的制作。
github地址https://gitcode.net/yudenggamer/cc6

一、PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划3060
· Estimate· 估计这个任务需要多少时间1010
Development开发100300
· Analysis· 需求分析 (包括学习新技术)60240
· Design Spec· 生成设计文档2020
· Design Review· 代码规范 (为目前的开发制定合适的规范)6090
· Design· 具体设计3040
· Coding· 具体编码120180
· Code Review· 代码复审6090
· Test· 测试(自我测试,修改代码,提交修改)60120
Reporting报告3070
· Test Repor· 测试报告2030
· Size Measurement计算工作量1010
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划1010
· 合计6201270

二、计算模块接口的设计与实现过程。

1.读写 txt 文件的模块readwrite类

类:readwrite
方法1:readTxt:读取txt文件
方法2:writeTxt:写入txt文件
实现:调用 Java.io 包提供的接口,进行简单的文件读取写入

2.计算Hash值的Hash类

我们实现论文查重的方法是SimHash算法。

算法原理:1、分词,把需要判断文本分词形成这个文章的特征单词。最后形成去掉噪音词的单词序列并为每个词加上权重。
2、Hash,通过hash算法把每个词变成hash值。
3、加权,通过 2步骤的hash生成结果,需要按照单词的权重形成加权数字串。
4、合并,把上面各个单词算出来的序列值累加,变成只有一个序列串。
5、降维。

详细算法:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.List;


import com.hankcs.hanlp.HanLP;      //注意!这个需要添加一个hanlp分词包。


public class Hash {


    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;
        }
    }                                                  //他就会“得到”这个分词的hash值

    //注意此时!
    
    
    
    public static String quanHash(String str){         //这个才会返回加权hash值
    	
    	 String simHash = ""; 
    	List<String> keywordList = HanLP.extractKeyword(str, str.length());//jar包派上用场,取出所有关键词
    
    	
    	int size = keywordList.size();
        int i = 0;
        int[]b=new int[128];
        
        
        
        
        
        
        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";
                }                           
               }           //这个是为了防止不够128,补上0,本身没啥大不了的
            
            
            
            
            //加权!
            
            for (int j = 0; j < b.length; j++) {       
               
                if (keywordHash.charAt(j) == '0')         // 他是一个字符串,我们0就是负
                {           
                    b[j] -= (10 - (i / (size / 10)));
                } 
                else                                      //1就是正,不是0就是1
                {
                    b[j] += (10 - (i / (size / 10)));
                }
            }
            
            
            
            i++;
        }
        
        
        
        //降维
        
        for (int j = 0; j < b.length; j++) {
            if (b[j] <= 0) 
            {
                simHash += "0";
            } else {
                simHash += "1";
            }
        }
        return simHash;
    }

    
}

3.计算海明距离hamming类

方法一:getHammingDistance
用来计算海明距离
方法二:getSimilarity
用来计算相似程度,输出最后结果

都比较简单

public class hamming 
{

    public static int getHammingDistance(String simHash1, String simHash2) {     //该算法用于计算海明距离,原理很简单,就是一个一个比较
        int Ham=0;
        int n=simHash1.length();
        
        
        
            for (int i = 0; i < n; i++) 
            {
                if (simHash1.charAt(i)== simHash2.charAt(i))   //charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
                {     
                	Ham+=1;
                }
            }
        
        return Ham;
    }

 
    
    
    
    
    
    public static double getSimilarity(String simHash1, String simHash2) 
    {
     
        int distance = getHammingDistance(simHash1, simHash2);
        return 0.01 * (100 - distance * 100 / 128);         //相似度计算
    }

}

4、main 主模块,cc主类

CC主类很简单,就是运用上面的模块
先输入两个txt文件的地址,他们是对比的两个文件
再输入你希望结果出现的txt文件
等待输出:程序运行完成,请检查结果吧!
就可以去查看结果了。

三、计算模块接口部分的性能改进

请添加图片描述

请添加图片描述

四、单元测试

注意,我是用eclipse测试的,因此这里又要加一个Jar包,Junit.jar。

1.Main类,cc类的测试Mainer类

public class Mainer {
	public static void main(String[] args) {
		String[] str = new String[7];
        str[0] = readwrite.read("D:/test/orig.txt");
        str[1] = readwrite.read("D:/test/orig_0.8_add.txt");
        str[2] = readwrite.read("D:/test/orig_0.8_del.txt");
        str[3] = readwrite.read("D:/test/orig_0.8_dis_1.txt");
        str[4] = readwrite.read("D:/test/orig_0.8_dis_10.txt");
        str[5] = readwrite.read("D:/test/orig_0.8_dis_15.txt");
        str[6] = "D:/test/ak47.txt";
		
		
		// 以上为从命令行输入的路径名读取对应的文件
		
        String str0 = Hash.quanHash(str[0]);
        String str1 = Hash.quanHash(str[1]);
        String str2 = Hash.quanHash(str[2]);
        String str3 = Hash.quanHash(str[3]);
        String str4 = Hash.quanHash(str[4]);
        String str5 = Hash.quanHash(str[5]);
        
     // 由字符串得出对应的 simHash值
        
     // 由 simHash值求出相似度
        double similarity = hamming.getSimilarity(str0, str1);
        readwrite.write(similarity, str[6]);
        double similarity1 = hamming.getSimilarity(str0, str2);
        readwrite.write(similarity1, str[6]);
        double similarity2 = hamming.getSimilarity(str0, str3);
        readwrite.write(similarity2, str[6]);
        double similarity3 = hamming.getSimilarity(str0, str4);
        readwrite.write(similarity3, str[6]);
        double similarity4 = hamming.getSimilarity(str0, str5);
        readwrite.write(similarity4, str[6]);
        // 把相似度写入最后的结果文件中
        
        
        
        
        
        System.out.println("程序运行完成,请检查结果吧!");
	}
	

}

代码覆盖率
请添加图片描述
请添加图片描述

输出文件

请添加图片描述

请添加图片描述

2.readwrite模块测试

import org.junit.Test;

public class readwritetest {

	    @Test
	    public void readTxtTest() {
	        // 路径存在,正常读取
	        String str = readwrite.read("D:/test/orig.txt");
	        String[] strings = str.split(" ");
	        for (String string : strings) {
	            System.out.println(string);
	        }
	    }
	    @Test
	    public void writeTxtTest() {
	        // 路径存在,正常写入
	        double[] elem = {0.11, 0.22, 0.33, 0.44, 0.55};
	        for (int i = 0; i < elem.length; i++) {
	            readwrite.write(elem[i], "D:/test/ans.txt");
	        }
	    }
	    @Test
	    public void readTxtFailTest() {
	        // 路径不存在,读取失败
	        String str = readwrite.read("D:/test/none.txt");
	    }
	    @Test
	    public void writeTxtFailTest() {
	        // 路径错误,写入失败
	        double[] elem = {0.11, 0.22, 0.33, 0.44, 0.55};
	        for (int i = 0; i < elem.length; i++) {
	        	readwrite.write(elem[i], "User:/test/ans.txt");
	        }
	    }
	}

代码覆盖率
请添加图片描述

请添加图片描述

3.Hash模块

import org.junit.Test;

public class HashTest {

    @Test
    public void getSimHashTest(){
        String str0 = readwrite.read("D:/test/orig.txt");
        String str1 = readwrite.read("D:/test/orig_0.8_add.txt");
        System.out.println(Hash.quanHash(str0));
        System.out.println(Hash.quanHash(str1));
    }
}

代码覆盖率
请添加图片描述
请添加图片描述

4.Hamming模块

import org.junit.Test;

public class HammingTest {
	    @Test
	    public void getHammingDistanceTest() {
	        String str0 = readwrite.read("D:/test/orig.txt");
	        String str1 = readwrite.read("D:/test/orig_0.8_add.txt");
	        String str2=Hash.getHash(str0);
	        String str3=Hash.getHash(str1);
	        double i=hamming.getSimilarity(str2,str3);
	      
	    }
	}
	

代码覆盖率
请添加图片描述

五、计算模块部分异常处理说明

读取异常,我们直接抛出并且添加一个输出以提醒,程序读取出错了。
Hash模块也有同样的操作。
输出同理。

try{
        	
        file1 = new FileInputStream(file);
        InputStreamReader read1 = new InputStreamReader(file1, "UTF-8");
        BufferedReader read2 = new BufferedReader(read1);       //将其转化为字符
		
        
        while(true)
        {
        	if((strLine = read2.readLine()) != null) {
            str += strLine;                  //如果下一行不空,我们就读下去        
        }            
        	else  break;
        }
        
        
        
        read1.close();
        read2.close();
        file1.close();   //关闭资源
        
        }
		catch(IOException e)
		{
			System.out.println("文件读取出错,请检查你的输入");
		}

六、总结

这次作业让我很清晰地认识到自己的不足,对项目开发缺乏经验,导致需要大量地查询很多没有学习过的资料,对这些资料的学习也耗费了大量的时间,而自己的Java程序开发的经验也仍有很大不足,编程速度比较慢,让我对自己目前的经验有了很深刻的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值