zoukankan      html  css  js  c++  java
  • 结对第二次作业

    结对第二次作业

    一,结对成员

    031602414 柯叶祥
    031602435 肖逸清

    • 分工
      我负责写代码,柯同学负责写单元测试。

    二,psp

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 10 10
    • Estimate • 估计这个任务需要多少时间 10 10
    Development • 开发 1210 1670
    • Analysis • 需求分析 (包括学习新技术) 400 500
    • Design Spec • 生成设计文档 10 10
    • Design Review • 设计复审 10 10
    • Coding Standard • 代码规范 (为目前的开发制定合适的规范) 10 10
    • Design • 具体设计 20 20
    • Coding • 具体编码 500 600
    • Code Review • 代码复审 60 120
    • Test • 测试(自我测试,修改代码,提交修改) 200 400
    Reporting 报告 30 40
    • Test Repor • 测试报告 10 10
    • Size Measurement • 计算工作量 10 10
    • Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 10 20
    合计 1250 1710

    三,解题思路描述与设计实现说明

    • 爬虫使用
      爬虫我用java实现,一开始找资料的时候在看SeimiCrawler,后来觉得太复杂换了jsoup。
      因为有导入外部jar包,为了方便新建了maven工程。
      添加pom依赖:
    <dependency>
      		<!-- jsoup HTML parser library @ http://jsoup.org/ -->
      		<groupId>org.jsoup</groupId>
      		<artifactId>jsoup</artifactId>
      		<version>1.10.2</version>
    	</dependency>
    

    接下来是具体实现部分,思路是先爬取每个文章的链接,再逐个爬取每个链接,获取标题和摘要。

    package cvpr;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    /**爬虫实现
     * 
     * @author xyq
     * @since 2018 10 10
     * @version 1.0
     */
    public class clawler {
    	
    	/**爬取cvpr网站
    	 * 
    	 * @return Map<String, String>
    	 * 
    	 */
    	public Map<String, String> getPaperInfo() {
    		Map<String, String> paperInfo = new HashMap<String, String>();
    		
    		
    		ArrayList<String> htmlLinks = new ArrayList<String>();
    		String head = "http://openaccess.thecvf.com/";//html链接前半部分
    		
    		try
    		{
    			Document doc = null ;
    			doc = Jsoup.connect("http://openaccess.thecvf.com/CVPR2018.py#").get();
    		    //Document document = Jsoup.parse(new File("C:/Users/zkpkhua/Desktop/yiibai-index.html"), "utf-8");
    		    Elements links = doc.select("dt a[href]");  
    		    for (Element link : links) 
    		    {
    
    		        	//System.out.println("link : " + link.attr("href")); 
    		        	htmlLinks.add(head+link.attr("href"));//得到html链接
    		        	//System.out.println(head+link.attr("href"));
    		    }
    		} 
    		catch (IOException e) 
    		{
    		    e.printStackTrace();
    		}
    		
    		try
    		{
    			for (String htmlLink : htmlLinks) {
    				Document doc = null ;
    				doc = Jsoup.connect(htmlLink).get();
    				Elements titleInfo = doc.select("div#papertitle"); 
    				Elements abstractInfo = doc.select("div#abstract"); 
    				//System.out.println(titleInfo.text());
    				paperInfo.put(titleInfo.text(), abstractInfo.text());
    			} 
    		   
    		} 
    		catch (IOException e) 
    		{
    		    e.printStackTrace();
    		}
    		return paperInfo;
    	}
    	
    	public void writeResult() throws Exception {
    		Map<String, String> paperInfo = new HashMap<String, String>();
    		clawler clawler = new clawler();
    		paperInfo = clawler.getPaperInfo();
    		String path = System.getProperty("user.dir")+"\src\main\java\cvpr\result.txt";
    		File file = new File(path);
    		StringBuilder result = new StringBuilder("");
    		int count = 0;
    		FileWriter filewriter = new FileWriter(file.getAbsoluteFile());
    		//System.out.println("absolutely path:"+file.getAbsolutePath());
    		BufferedWriter bufferedWriter = new BufferedWriter(filewriter);
    		
    		
    		for (Entry<String, String> entry : paperInfo.entrySet()) {
    			result.append(count);
    			count++;
    			result.append("
    ");
    			result.append("Title:"+entry.getKey());
    			result.append("
    ");
    			result.append("Abstract:"+entry.getValue());
    			result.append("
    ");
    			result.append("
    ");
    			result.append("
    ");
    			//System.out.println("title:  "+entry.getKey());
    			//System.out.println("abstract:  "+entry.getValue());
    		}
    		
    		
    		
    		bufferedWriter.write(result.toString());
    		
    		bufferedWriter.close();
    	}
    }
    
    • UML类图
      UML类图

    • 流程图
      流程图

    • 关键实现部分流程图
      这次的关键在于新增的词组统计功能,一下是实现的流程图。
      在这里插入图片描述


    四,附加题设计与展示

    设计的创意独到之处

    爬取每篇文章的作者信息,统计各个作者的文章数量。

    实现思路

    先爬取每篇文章的链接,再对这些链接爬取获取作者的名字,将结果排序输出至文件。

    成功展示

    在这里插入图片描述


    五,关键代码展示

    /**排序,按权重降序
         * 
         * 
         */
    private static void sort(ArrayList<HashMap.Entry<String, Integer>> wordList) {
            Collections.sort(wordList, new Comparator<HashMap.Entry<String, Integer>>() {
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                    if (o1.getValue() < o2.getValue()) {
                        return 1;
                    } else {
                        if (o1.getValue().equals(o2.getValue())) {
                            if (o1.getKey().compareTo(o2.getKey()) > 0) {
                                return 1;
                            } else {
                                return -1;
                            }
                        } else {
                            return -1;
                        }
                    }
                }
            });
    }
    

    获取命令行参数

     /* 
             * 这里先取默认值,因为不是所有参数都会被用户提供 
             */  
            String in = " ";
            String o = " ";
            int m = 1;
            int n = 10;
            int w = 1;
            
            long charNum = 0;
            long lineNum = 0;
            long wordNum = 0;
            /* 
             * 设置一个offset变量,用来定位相关信息 
             */  
            int optSetting = 0;  
            for (; optSetting < args.length; optSetting++) {  
                if ("-i".equals(args[optSetting])) {  
                    in =  args[++optSetting];
                } else if ("-o".equals(args[optSetting])) {  
                	o =  args[++optSetting];  
                } else if ("-m".equals(args[optSetting])) {  
                    m =  Integer.parseInt(args[++optSetting]); 
                } else if ("-n".equals(args[optSetting])) {  
                	n =  Integer.parseInt(args[++optSetting]); 
                } else if ("-w".equals(args[optSetting])) {  
                	w =  Integer.parseInt(args[++optSetting]);  
                }          
            }  
    

    六,性能分析与改进&单元测试&签入记录

    • 思路
      因为第一次测试的结果不理想,知道了是在分词方面出了问题。所以这次的分词部分不再偷懒用自带方法,而是运用了自动机的思想逐字符地拼凑单词。
    				for(;i < str.length();i++) {
                    		//大写字母转为小写字母
                    		temp = str.charAt(i);
                            if ((temp >= 65) && (temp <= 90)) {
                                temp += 32;
                            }
                            
                            if(state == 0) {
                            	if ((temp >= 97) && (temp <= 122)) {
                                    word.append(temp);
                                    state = 1;
                                }
                            	
                            }else if (state == 1) {
                            	if ((temp >= 97) && (temp <= 122)) {
                                    word.append(temp);
                                    state = 2;
                                } else {
                                    word.setLength(0);
                                    state = 0;
                                }
    							
    						}else if (state == 2) {
    							if ((temp >= 97) && (temp <= 122)) {
                                    word.append(temp);
                                    state = 3;
                                } else {
                                    word.setLength(0);
                                    state = 0;
                                }
    						}else if (state == 3) {
    							if ((temp >= 97) && (temp <= 122)) {
                                    word.append(temp);
                                    state = 4;
                                } else {
                                    word.setLength(0);
                                    state = 0;
                                }
    						}else if (state == 4) {
    							if (((temp >= 97) && (temp <= 122)) || ((temp >= '0') && (temp <= '9'))) {
                                    word.append(temp);
                                } else {
                                    wordlist.add(word.toString());
                                    word.setLength(0);
                                    state = 0;
                                }
    						}                    
                            
                    	}
                    	if (state == 4) {
                            wordlist.add(word.toString());
                        }
    
    • 单元测试
      思路就是用白盒测试,事先计算好测试用例的期望值,与输出对比
    	@Test
    	public void testPhraseFrequency2_1() {
    		phraseFrequencyCounter phraseFrequencyCounter = new phraseFrequencyCounter();
    		int topPhrasenum = 0;
    		ArrayList<HashMap.Entry<String, Integer>> wordList = new ArrayList<HashMap.Entry<String, Integer>>();
    		HashMap<String, Integer> wordlistMap = new HashMap<String, Integer>();
    		wordlistMap = phraseFrequencyCounter.countPhraseFrequency("D:\java_project\031602435&031602414\src\test\java\wordCount2_031602435\"+"result.txt",1,3);
    		wordList = phraseFrequencyCounter.topFrequentPhrases(wordlistMap);
    		topPhrasenum = wordList.get(0).getValue();
    		assertEquals(97, topPhrasenum);
    		
    	}
    	@Test
    	public void testWordNum1() {
    		wordNumberCounter wordNumberCounter = new wordNumberCounter();
    		long wordnum =wordNumberCounter.countWord("D:\java_project\031602435&031602414\src\test\java\wordCount2_031602435\"+"text1.txt");
    		System.out.println(wordnum);
    		assertEquals(9, wordnum);
    		
    	}
    	
    	@Test
    	public void testPhraseFrequency1_1() {
    		phraseFrequencyCounter phraseFrequencyCounter = new phraseFrequencyCounter();
    		int topPhrasenum = 0;
    		ArrayList<HashMap.Entry<String, Integer>> wordList = new ArrayList<HashMap.Entry<String, Integer>>();
    		HashMap<String, Integer> wordlistMap = new HashMap<String, Integer>();
    		wordlistMap = phraseFrequencyCounter.countPhraseFrequency("D:\java_project\031602435&031602414\src\test\java\wordCount2_031602435\"+"text1.txt",1,3);
    		wordList = phraseFrequencyCounter.topFrequentPhrases(wordlistMap);
    		topPhrasenum = wordList.get(0).getValue();
    		assertEquals(11, topPhrasenum);
    		
    	}
    	
    
    • commit记录
      commit

    这次的用时虽然有20多小时,但是完成总时间是在两天半(不包括学习技术)。。所以只有一条记录。

    七,遇到的代码模块异常或结对困难及解决方法

    • 问题
      一开始没接触过爬虫,不知道怎么使用
    • 尝试
      找资料,看博客,按上面的方法摸索,结合着看文档。
    • 是否解决
      已经解决
    • 收获
      学习到了爬虫的简单使用

    八,评价队友

    认真负责

    九,进度

    java:2->2.4
    自主学习能力:2->2.6

  • 相关阅读:
    添加事件(jquery)
    闭包导致的问题
    学习之js绑定事件
    第二条 一个类如果有多个参数,考虑用Builder构造者模式
    用Intellij IDEA 创建第一个maven项目!
    OrderSessionHelper查看订单在session是否存在的辅助类
    css——overflow
    css——盒子
    css——外部样式
    css——权重叠加
  • 原文地址:https://www.cnblogs.com/daydreams/p/9781184.html
Copyright © 2011-2022 走看看