HW—词频统计

第一次个人作业——词频统计

第一次做这种大作业,明显感觉陌生,各种规范和技能也是第一次使用,希望自己好运。

目录:一、基本要求

           二、需求分析及时间估计

           三、实现思路及过程

           四、测试用例、时间性能分析及改进方法

           五、经验总结

  

一、基本要求  

1. 统计文件的字符数(只需要统计Ascii码,汉字不用考虑,换行符不用考虑,'\0'不用考虑)(ascii码大小在[32,126]之间)

2. 统计文件的单词总数

3. 统计文件的总行数(任何字符构成的行,都需要统计)(不要只看换行符的数量,要小心最后一行没有换行符的情形)(空行算一行)

4. 统计文件中各单词的出现次数,输出频率最高的10个。

5. 对给定文件夹及其递归子文件夹下的所有文件进行统计

6. 统计两个单词(词组)在一起的频率,输出频率最高的前10个。

7. 在Linux系统下,进行性能分析,过程写到blog中(附加题) 

注意:

a) 空格,水平制表符,换行符,均算字符

b) 单词的定义:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。

分割符:空格,非字母数字符号

例如:”file123”是一个单词,”123file”不是一个单词。file,File和FILE是同一个单词。

如果两个单词只有最后的数字结尾不同,则认为是同一个单词,例如,windows,windows95和windows7是同一个单词;

输出按字典顺序,例如,windows95,windows98和windows2000同时出现时,输出windows2000

c)词组的定义:windows95 good, windows2000 good123,可以算是同一种词组。按照词典顺序输出。

两个合法单词之间,出现一个非法字符串,比如:windows2000 abc good123,因为abc按照定义不是单词,因此这个词组其实是windows2000 good123,中间的abc当做分隔符看待。

两个单词分属两行,也可以直接组成一个词组。统计词组,只看顺序上,是否相邻。

d) 输入文件名以命令行参数传入。需要遍历整个文件夹时,则要输入文件夹的路径。

e) 输出文件result.txt

characters: number

words: number

lines: number

<word>: number

<word>为文件中真实出现的单词大小写格式,例如,如果文件中只出现了File和file,程序不应当输出FILE,且<word>按字典顺序(基于ASCII)排列,上例中程序应该输出File: 2

f) 根据命令行参数判断是否为目录

g) 将所有文件中的词汇,进行统计,最终只输出一个整体的词频统计结果。

 

二、需求分析及时间估计

1.统计字符总数及行数;

2.甄别单词并予以统计;

3.甄别词组并予以统计;

4.根据频率对单词、词组各自排序;

5.实现对文件夹及子文件夹的遍历;

PSP表格:

 

 

由表可看出,大部分阶段都是超时完成的,亟需改进;整体来看效率也比较低。

 

三、实现思路及过程

*结构体定义

 

1.统计字符总数及行数

这个就是遍历一下文件,遇到ascii值在32~126之间的就计数,行数统计则是统计换行符的个数,针对最后一个字符表示换行符的文件额外再加一即可。

 

2.甄别单词并予以统计

从文件第一个字符开始或者从某一分隔符开始,若检测到字母则开始借助flag标志辨别单词,当连续字母达到四个时说明找到单词,之后继续扫描并依次写入临时数组直到遇见分隔符;如果在连续遇到1~3个字母后被打断,则用标志mark判断若被数字打断则当前字符串作废,继续扫描直到遇见分隔符然后开始下一次单词甄别,如果是被分隔符打断则可以直接开始寻找下一个单词。注意最后退出的时候要判断一下当前字符串是否为单词。

统计部分则是在上述代码中增设一个临时数组b,实时存储字符串,当字符串无效时清空该数组,直到其为一个合法的单词,此时将其插入哈希表,通过单词首字母确定52个元素,按自然顺序1~52构造其哈希地址,用常数52定址解决冲突,若遇到等价的单词则判断字典顺序决定是否覆盖,若没有则新占一个槽。下面是哈希部分的代码:

 

 

3.甄别数组并予以统计

这部分我没什么好的思路,基本就是每次成功甄别到一个单词就用临时数组temp记录它,当下一个单词找到时,就把temp和b代入哈希函数去寻址(以temp首字母为自变量),哈希表构造与操作同上。套路与单词统计基本一致,代码不再展示。

 

4.根据频率对单词、词组各自排序

由于只需要输出频率最高的10个单词及10个词组,堆排序是最好的方式。

数组a按序包含了所有单词在word结构体数组(也就是哈希表)中的下标。算法是以单词频率为排序依据,对每个单词在word数组中的下标进行排序,当已经排好前十个时停止排序并打印结果。对词组的排序与之相同,不再赘述。

 

5.实现对文件夹及子文件夹的遍历

 查阅资料之后得知可以用句柄递归遍历文件夹,从而获取当前文件夹里所有文件的路径,然后处理一下将路径中的‘ \ ’换成 ‘ / ’即可被fopen调用来打开文件了。

getFiles函数用于获取当前文件夹下所有文件的路径。

 

完整的源代码地址:https://github.com/ustcychu/HW1_PB16060445.git

 

四、测试用例及时间性能分析

1.第一次调试用了个555k的文件夹,然后用了7.688秒orz,所以就靠优化工作了。

主函数中的热行当然在于调用分析函数statistics()。

 

 

statistics函数中的热行在于两次构造哈希表查找空槽和判断是否等价的过程,而且词组部分的耗时明显高于单词部分。

 

所以首先该分析的是JudgeWordEqual函数。其大致工作流程是判断俩字符串长度大小关系然后从后往前扫描,如果最后一段数字之前(如果有的话)的部分等价就判定俩单词等价,然再从头遍历判断二者字典顺序并予以覆盖,方便后续操作。

分析结果显示,大部分判断长度大小关系的结果都是二者相等,所以应放在第一个判断从句;用strlen取字符串长度耗时较多;上述两次遍历时间太长。

因此决定先针对性优化,效果不好就尝试别的方法。经过改进,时间缩至6.56秒。

接着我又重写了一种方法:

从两个字符串末尾开始扫描直到非数字的字符,将这之前的字符串片段取出进行不区分字母大小写的比较(stricmp),若匹配则说明俩字符串等价,然后用strcmp判断二者字典顺序选择是否进行覆盖,方便之后的操作。

 

似乎有了进步—5.01秒,但好像也不是特别好qaq。

再在lb--后面加上判断la与lb是否相等的判断以避免不必要的运算—时间缩至4.833秒。

之后再经过分析认为可能是哈希函数的问题,于是作了修改(主要就是扩大哈希函数的值域以减少搜索):

对应的查找与插入:

事实上,哈希函数如果给自变量加权的话可能效果更好,还有散列函数还可以选择二次探测法和拉链法(有时间的话再写一份拉链法的毕竟指针操作快很多 可惜开始没有想到),出于时间限制没有继续写下去了。

此次修改之后对应时间缩至1.633秒(还是有了一点点效果)。

 

2.测试空文件

(按要求空文件也记行 虽然不知道为啥要记...)

3.测试只有一个单词的文件

4.测试只有一行的文件:hhhh a1hhh hhhh lalalala

5.其他测试集 ( 优化前) 

A.(27k,0.018s)

B.(32k,0.024s)

 

C.(1M, 5.243秒)

 

6.其他测试集(优化后)

A.(1.2M, 2.56秒)

 

B.(5.2M,3.791秒)

 

C.(21M, 11.143秒)

附时间性能分析

可以看出代码的热行没有改变,改动的两个地方(JudgeWordEqual和哈希函数)的时间性能好了很多。

很明显可优化的地方还很多,今后继续学习逐渐进步。

 

 ***标准测试集(177M,21min)***

 

五、经验总结

通过本次实验,回顾了不少编程知识,也在看书浏览博客的过程中收获了很多技能;与之前的编程经历相比进步在于编程增加模块功能时结构更清晰、语句整理更熟练、细节bug明显减少,但在代码运行效率方面还有很大的进步空间,首先需要学习更多更高级的语言和工具,目前也是在进行中为团队项目做准备,其次是在编程算法上有待锻炼,目前感觉还是太老套,需要更多的阅读积累。希望通过本学期的学习能够很好地提升自己的软件编程能力,为今后做好准备。

 

转载于:https://www.cnblogs.com/notegeek/p/8654847.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GDB技巧:使用checkpoint解决难以复现的Bug

本文的copyleft归gfree.windgmail.com所有&#xff0c;使用GPL发布&#xff0c;可以自由拷贝&#xff0c;转载。但转载请保持文档的完整性&#xff0c;注明原作者及原链接&#xff0c;严禁用于任何商业用途。作者&#xff1a;gfree.windgmail.com博客&#xff1a;linuxfocus.bl…

php数组取字段值,php如何获取二维数组指定的某个字段的值

php怎么获取二维数组指定的某个字段的值&#xff1f;需求&#xff1a;有如下数组$arr&#xff0c;数组中有两个模块一个net 一个login&#xff0c;我怎么根据net模块获取最后一个marks,其中net模块和login模块的数据还是一条一条正往$arr里插&#xff0c;net模块亦可能是 find …

【uoj#209】[UER #6]票数统计 组合数+乱搞

题目描述 一个长度为 $n$ 的序列&#xff0c;每个位置为 $0$ 或 $1$ 两种。现在给出 $m$ 个限制条件&#xff0c;第 $i$ 个限制条件给出 $x_i$ 、$y_i$ &#xff0c;要求至少满足以下两个条件之一&#xff1a; 序列的前 $x_i$ 个位置中&#xff0c;恰好有 $y_i$ 个 $1$ &#x…

linux下解压.tar.bz2文件

方式1&#xff1a; 4 teps&#xff1a; 1、bunzip2 <file>.tar.bz2 2、tar xf <file>.tar 3、cd /<file> 4、 ./configure 方式2&#xff1a; tar -jxvf <file>.tar.bz2

中医 西班牙语 PHP,php – MySql西班牙语字符数据

我有一个包含西班牙语字符的数据库.填充数据库我从客户端页面获取具有字符编码 UTF-8的值.当我在mySql数据库中插入值时,行包含更改的数据.例如,如果我插入’Mxico’,数据库中的条目是’M©xico’.这有什么影响,当我在指定’Mxico’的表上进行查询时,我得不到任何结果.我的…

oFono安装和启动

安装和启动oFono 1. git clone git://git.kernel.org/pub/scm/network/ofono/ofono.git 2. cd ofono 3. ./bootstrap-configure 或者./configure. configure过程中你可以需要装一些依赖包, 如&#xff1a; sudo apt-get install libudev-dev libdbus-1-dev libcap-ng-dev libto…

寻找三角形

在无向图中&#xff0c;如果三个不同的顶点之间都有边&#xff0c;则称他们组成了一个三角形。 在一张无向图 G 中&#xff0c;有且仅有一个三角形。现在你的任务是找到它。 输入格式 第一行两个数 $n, m$&#xff0c;表示 G 的顶点个数和边的条数。 接下来 $m$ 行&#xff0c;…

PHP封装curd,CURD · TookPHP开发手册 · 看云

## CURD* 开启 DEBUG 模式后&#xff0c;所有SQL语句均会在调试窗口显示&#xff0c;一目了然.[TOC]### find 单条查询通过 find 操作进行简单的单条查询操作。~~~//查找主键值为 18 的记录$db->find(18);~~~### all 查询(别名 select)通过 all 查找所有记录数 。~~~//查找表…

MemCache 分布式缓存

引用&#xff1a;http://baike.baidu.com/view/1193094.htm Memcache是一个高性能的分布式的内存对象缓存系统&#xff0c;通过在内存里维护一个统一的巨大的hash表&#xff0c;它能够用来存储各种格式的数据&#xff0c;包括图像、视频、文件以及数据库检索的结果等。简单的说…

全排列问题(递归)

上次上课老师讲了全排列算法&#xff0c;现在刚刚看自己的写的全排列算法&#xff0c;看了好一会才看懂。。。。 应该是自己理解的不够彻底 所以今天彻彻底底的来分析一下 先看图&#xff1a; 思路&#xff1a; 先固定一个字符&#xff0c;然后将固定的字符与它后面的每一个进行…

asp mysql 连接字符串,在ASP中连接数据库(连接字符串)

一、存取数据库的原理在ASP中&#xff0c;用来存取数据库的对象统称ADO对象(Active Data Objects)&#xff0c;主要含有三种对象&#xff1a;Connection、Recordset和Command&#xff0c;其中Connection负责打开或连接数据库&#xff0c;Recordset负责存取数据表&#xff0c;Co…

Windows 7/Vista 桌面上为何有两个隐含的 Desktop.INI

笔者今天在微软中文论坛看到有人又问起一个不算新问题的问题&#xff1a;当我们通过 Windows 7/Vista 的文件夹 选项设置允许显示隐含的文件后&#xff0c;会在 Windows 7/Vista 桌面上看到两个同名的 Desktop.INI 隐含文件&#xff1b; 而在 Windows XP 中允许显示隐含的文件却…

@Autowired @Resource @Inject 自动注入

一、AutoWired ( spring 的注解 )自动注入 /*** Autowired:* 默认按照 Student 类型去容器中找对应的组件:applicationContext.getBean(Student.class);* 如果找到多个相同类型的组件&#xff0c;再将 student 这个属性名作为 id 去容器中找对应组件 applicati…

峰Redis学习(8)Redis 持久化AOF方式

第三节&#xff1a;Redis 的持久化之AOF 方式       AOF方式&#xff1a;将以日志&#xff0c;记录每一个操作优势&#xff1a;安全性相对RDB方式高很多&#xff1b; 劣势&#xff1a;效率相对RDB方式低很多&#xff1b; 1&#xff09;AOF方式需要配置&#xff1a; # Ple…

移动web开发框架之我见

目前开发移动程序框架选择很多&#xff0c;从Web App&#xff0c;到PhoneGap&#xff0c;Titanium&#xff0c;MonoTouch&#xff0c;再到Native App&#xff0c;总有一款适合你。规律是&#xff0c;兼容性越强的技术&#xff0c;成本越低&#xff0c;性能越差&#xff1b;兼容…

php内核介绍及扩展开发指南,4.5. 发布扩展信息

发布扩展信息扩展可以发布 phpinfo() 或反射API要求的信息。我们一起来看一下。本章不会太长&#xff0c;因为真的很简单。MINFO( ) 挂钩如果声明了&#xff0c;一切都在声明的 MINFO() 挂钩中进行。如果未声明&#xff0c;则引擎将运行默认功能以打印有关扩展名的信息。该功能…

2011年度中国地区网络安全威胁大事记

2011年6月28日晚20时左右&#xff0c;新浪微博突然爆发“病毒”&#xff0c;大批用户中招&#xff0c;“中毒”用户点击恶意链接后便并自动关注一位名为hellosamy的用户&#xff0c;之后开始自动转发微博和私信好友来继续传播恶意地址。不少认证用户中招&#xff0c;也导致该“…

ansible模块介绍

ansible 默认提供了很多模块来供我们使用。在 Linux 中&#xff0c;我们可以通过 ansible-doc -l 命令查看到当前ansible 都支持哪些模块&#xff0c;通过 ansible-doc -s 模块名 又可以查看该模块有哪些参数可以使用。 下面介绍比较常用的几个模块 copy模块file模块cron模块gr…

matlab迭代次数,怎么知道程序中的迭代次数呢

function [result,x,y]TS_BS1(num_1,num_2,c_i,d_j,M_i,T)%初始参数设置runcount 0;tabulength 3 num_1;candidate.x round(rand(1,num_1));y zeros(num_1,num_2);sum_d 0;for i 1:num_2sum_d sum_d d_j(i);endalfa 0.9;%初始化禁忌表for i 1:tabulengthtabulist(i)…

使用a标签调用手机系统的一些小技巧(打电话、发短信)

拨打电话&#xff1a; <a href"tel:181181181181">call me!</a> 号码前加“”&#xff0c;表示国际号码 <a href"tel:110">110</a> 发送短信&#xff1a; <a href"sms:123456789">给123456789发短信</a> …