软件工程个人作业 词频统计

  软件工程个人作业

——单词频率统计

曾子轩

School of information,USTC

一、项目介绍与分析(作业要求:http://www.cnblogs.com/denghp83/p/8627840.html)

  项目介绍:

    1. 统计文件的字符数

    2. 统计文件的单词总数

    3. 统计文件的总行数

    4. 统计文件中各单词的出现次数,对给定文件夹及其递归子文件夹下的所有文件进行统计

    5. 统计词组的频率在Linux系统下,进行性能分析,过程写到blog

  项目分析:

   1、前三个要求限定了对单个字符的读取和处理

    2、第四个要求限定了对文件夹进行遍历、单词字符串的判别、处理和存储

    3、第五个要求限定了对前后字符串关系的存储

   数据结构的选定:

    1、因为对单词的判定是至少以四个字母开始,而之后的位数不定,为了体现各个不同前缀之间的区别,也是为了分散各个单词,所以采用通过前四个字母算出地址码(不同前缀对应不同地址)的方法将数据分散  在26^4=456976个单元中(命名为HashSet[456976])。            

    2、为了存储不定数目单词,又因为每一个单词节点数据较多,所以采用链表形式,且将带头结点的链表首地址存放在数组单元中。

       为了将词组更高效的存储,将跟在这个单词后面的单词的指针存储在前面这个单词结构体所指向列表(自行编写的变长数组)里。        

      WordNode      软件工程个人作业 词频统计

    3、在最后遍历时,因为只需要频率最大的十个单词、词组,所以采用数组的插入排序法,考虑到大多数单词/词组的出现次数只会比这个TopTen数组的最小出现次数小,所以从第十位开始比较、移动。

      TopWordStru    

软件工程个人作业 词频统计

二、项目进展

   各部分估计用时与实际用时:

       

软件工程个人作业 词频统计

    接下来对助教提供的大小为176MB的文件夹进行读取分析:

      

软件工程个人作业 词频统计   软件工程个人作业 词频统计

  2、对可以预知次数的循环函数进行拆分

    这是一种比较过分的优化,目的是消除计数器count自加、空间消耗的影响。实际上这样的影响甚微,反倒让代码难读,以致最后优化阶段出现失误,得不偿失。

  3、对If函数进行细分、优化

    如果一个if判断中包含多个或(||),不妨分成几个if嵌套,这样可以让操作分流,减少一些数据的判断次数,实际上这样的操作让我的代码快了数秒(因为调用次数实在太多)。

  4、对sizeof的优化

    因为数据结构的选择,让运行过程中充满了动态内存申请、分配,而每一次分配都计算一次sizeof显然是很不值得的,当然可以先通过编译器跑一次,然后作为宏定义值替换,但这样移植性受到限制,更好的做法是在函数中作   为静态变量调用。

 

 五、项目经验与反思

  1、关于本次程序本身

   1) 分配不均。根据前四个单词算出地址码是最简单的一种操作,但也不适应用实际中一些较大的应用,因为单词的出现频率并不是均匀的,比如以e开头的单词就明显多于以i、j、k字母开头的单词,当然我们这      样设计的程序是最适应于未知情况的。

  2、关于过程的体验

   1) 编码前细致入微的思考。本次工程很得益于实际编码前周全的思考,让最重要的代码很流畅地通过,以致最后出错的也不是这一部分的代码。在接下来的团队项目中,我也将继续这一设计理念,在功能确定      后,实际编码前细致地考虑每一步的实现,考虑可能出现的漏洞。 

   2) deadline的急躁。为了进行尽可能的所谓的优化,就跳过了严密的分析阶段,结果把程序改错而逾期,无力回天。

   3) 程序数据结构与接口定义清晰、参数没有歧义。在编写稍微大一点的程序的时候,就算是一人编写,也需要注意这个问题,否则编写到最后很可能一团糟,幸好本次较早地意识到这个问题,代码编写较为流      畅。

  

 六、跨平台的思考与实践

 

   在实现了Windows平台上的词频统计,便转到Linux平台上测试,其中程序中最重要的变化莫过于文件的遍历,因为Linux系统是不支持io.h的(但支持stdio.h)。

  

  一些比较重要的注意点归纳      参考(https://www.jianshu.com/p/f2fcd4628c12)

  open系统调用

    open系统调用建立了一条从到文件或设备的访问路径,该调用将得到与该文件相关联的文件描述符(file discriptor)

 

  write系统调用

    write系统调用把缓冲区buf中的前n个bytes写入与文件描述符fd相关的文件中。

  read系统调用

    read系统调用从与文件描述符fd相关联的文件中读入nbytes字节的数据,并把它们放到buf中。

  

  close系统调用

    close调用终止文件描述符fd与其对应文件之间的关联。文件描述符被释放并能够重新使用。close调用成功时候返回0,出错时返回-1。

  lseek系统调用

    lseek系统调用对文件描述符的读写指针位置进行设置> 参数whence定义该偏移量offset的用法,可取下列值

  fstat stat lstat系统调用

    fstat系列调用返回与打开的文件描述符相关联的文件的状态信息,该信息将被写入buf中。
    stat和lstat返回的使通过文件名查询到的状态信息。它们产生相同效果,但当文件是符号链接时,lstat返回的是该符号链接本身的信息,而stat返回的使该链接指向文件的信息。

转载于:https://www.cnblogs.com/Trinidad/p/8679202.html

相关资源:下拉通刷词软件v3.1.zip-其它代码类资源-CSDN文库

来源:weixin_30746117

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年2月26日
下一篇 2018年2月27日

相关推荐