202103226-1 编程作业

 

这个作业属于哪个课程 18级计科-软件工程4班
这个作业要求在哪里 202103226-1 编程作业
这个作业的目标 熟悉软件开发的实现过程
参考文献 eclipse测试单元参考等等

作业描述

在大数据环境下,搜索引擎,电商系统,服务平台,社交软件等,都会根据用户的输入来判断最近搜索最多的词语,从而分析当前热点,优化自己的服务。首先当然是统计出哪些词语被搜索的频率最高啦,请设计一个程序,能够满足一些词频统计的需求。

需求

  1. 统计文件的字符数(对应输出第一行):

    • 只需要统计Ascii码,汉字不需考虑
    • 空格,水平制表符,换行符,均算字符
  2. 统计文件的单词总数(对应输出第二行),单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。

    • 英文字母: A-Z,a-z
    • 字母数字符号:A-Z, a-z,0-9
    • 分割符:空格,非字母数字符号
      例:file123是一个单词, 123file不是一个单词。file,File和FILE是同一个单词
  3. 统计文件的有效行数(对应输出第三行):任何包含非空白字符的行,都需要统计。

  4. 统计文件中各单词的出现次数(对应输出接下来10行),最终只输出频率最高的10个。

    • 频率相同的单词,优先输出字典序靠前的单词。
      例如,windows95,windows98和windows2000同时出现时,则先输出windows2000
    • 输出的单词统一为小写格式

Gitee项目地址

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划
Estimate 估计这个任务需要多少时间 0.5h 1h
Development 开发
Analysis 需求分析 (包括学习新技术) 30h 28h
Design Spec 生成设计文档 3h 3.5h
Design Review 设计复审 1h 1h
Coding Standard 代码规范 (为目前的开发制定合适的规范) 0.5h 0.5h
Design 具体设计 2h 2.5h
Coding 具体编码 10h 14h
Code Review 代码复审 1h 1h
Test 测试(自我测试,修改代码,提交修改) 3h 4h
Reporting 报告 2h 2h
Test Repor 测试报告 1h 1h
Size Measurement 计算工作量 0.2h 0.1h
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 1h 1h
合计 55.2h 59.6h

解题思路

  1. 初看到题目只觉得思绪混乱,有很多知识都忘记了,于是仔细看了题目需求之后,大致估计了需要用到的知识,然后拿着以前的教材复习去了;
  2. 然后根据几个需要的功能,整体的思路是先分别设计几个方法,然后调用,但是对于能用命令行的方式执行这个程序的要求,留到最后解决。

代码规范

设计与实现

  • 首先设计一个main方法,通过这个main方法调用读取文件的方法,如下:
String inFileName = args[0];
        String outFileName = args[1];

        Lib lib = new Lib();
        File outFile = new File(outFileName);
        try {
            if (!outFile.exists())
                outFile.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
  • 承载读取出来的文件内容的参数作为输入参数,分别调用对应的实现方法,如下:
charters = lib.CountChar(lib.Readfile(inFileName));
        wordsNum = (int)lib.CountWords(lib.Readfile(inFileName));
        lines = lib.CountLines(lib.Readfile(inFileName));

        lib.CountWordsNum(lib.Readfile(inFileName),wordsNum);
        count = lib.GetCount();
        words = lib.GetWords();
  • 得到的结果作为返回值;再做一个写入文件的方法,按照需求将得到的结果写入一个输出文件中。
fileWriter = new FileWriter(outFile);
            fileWriter.write("characters: "+charters+"\n");
            fileWriter.write("words: "+wordsNum+"\n");
            fileWriter.write("lines: "+lines+"\n");
            for (int i=0; i<words.length && count[i]!=0; i++)
                fileWriter.write(words[i] + ": " + count[i] + "\n");

            fileWriter.close();

  • 主要功能方法中,统计字符数的方法,调用read()方法逐个以数字的形式读取文本的字符,以ASCII值判断字符
while((charnum=text.read())!=-1) {   //text.read()逐个以数字的形式读取文本的字符
				if(charnum < 128 && charnum >=0)
					number++;
			}
  • 统计单词数的方法中,单词只由字母或数字组成,且不能由数字开头
while((oneword=text.read())!=-1) {
				char ch = (char)oneword;
				
				if(ch >= 'a' && ch <= 'z' 
				   ||ch >= 'A' && ch <='Z'
				   || ch >= '0' && ch <= '9')
				     s=s+ch;
				else {
					if(s != null && Yes(s))
						number++;
					String t = null;
					s = t;
				}
			}
  • 统计有效行数方法,用正则表达式,将只有空白字符的行去掉
while((str = text.readLine()) != null) {
				//“\\s”是正则表达式,表示所以空白字符(换行、空格等),将这些空白字符换掉
				String temp = str.replaceAll("\\s","");
				if(str.length()!=0)
					rows++;
			}
  • 统计单词频数方法,将符合要求的单词搜寻一次,如果没有相同的,就存入数组中,如果有相同的,则频数加1
while((oneword = text.read())!=-1) {
			   char ch = (char)oneword;
			   
			   if(ch >= 'a' && ch <= 'z' 
					   ||ch >= 'A' && ch <='Z'
					   || ch >= '0' && ch <= '9') {
				   if(str == null) {
					   String tem = new String();
					   str = tem;
				   }
				   str=str+ch;
			   }else {
				   if(str!="" && Yes(str)) {
					   String temp = str.toLowerCase();
					 //单词不在数组中,则存入计数 ,已在数组中,则频数加1
					   if(!Ifexist(words,temp,counts) && j<words.length) {
						   words[j] = str;
						   counts[j]++;
						   if(j == words.length-1)
							   break;
						   j++;
					   }
					   str = null;   
				   }
			   }  
  • 对单词按频数排序,使用排序的算法,按频数从大到小排列,频数相同时,用compareTo()方法比较两个单词的大小,并排序
if (counts[i]<counts[j]){
                    //交换两个单词的频数的位置
                	int temp;
                    temp = counts[j];
                    counts[j] = counts[i];
                    counts[i] = temp;
                	//交换两个单词的位置
                    String tempS = new String ();
                    tempS = words[j];
                    words[j] = words[i];
                    words[i] = tempS;
                }
                else if (counts[i]==counts[j]) {
                    if (words[i].compareTo(words[j]) > 0){
                    	//交换两个单词的频数的位置
                        int temp = counts[j];
                        counts[j] = counts[i];
                        counts[i] = temp;
                    	//交换两个单词的位置
                        String tempS = new String ();
                        tempS = words[j];


                        words[j] = words[i];
                        words[i] = tempS;
                    }
                }

改进

对于读取文件的方式,一开始是打算直接用Writer 和Reader类的,然后知道使用到缓冲区会更便捷,于是改成了BufferedReader类;

测试

主要测试Lib中的方法,

  • 几个运行的测试

异常处理

基本上对每个方法都进行的

try{
    //操作
}catch(Exception e){
   //基本错误提示
}

收获

  • 一写起代码来就发现有太多知识已经忘记了,然后去翻了教材,主要回顾的还是IO这一章的内容,后续还要继续复习其它的内容;
  • 很久没用git了,用起来特别的生疏,查了好多的教程,磕磕绊绊的勉强做好了;
  • 以前从来没有接触过测试这一方面,这次突然要用才去查了相应的资料,有一些方法不知道怎么测,但是也写了几个测试,对测试这方面的内容算是有了初步的接触了;
  • 代码写的时候觉得没什么问题,写完之后进行测试时才发现有好几个小bug,暂时还没改,等改成了再来更新。
posted @ 2021-04-02 18:12  LeeMayZ  阅读(46)  评论(0编辑  收藏  举报