输出文本的词频统计和单词位置

输⼊

保证输⼊的字符中只出现以下字符:

  1. ⼤⼩写字⺟
  2. '-'连接符(减号)
  3. 逗号’,’
  4. 句号’.’
  5. 感叹号’!’(半⻆英⽂感叹号) (new!)
  6. 问号’?’(半⻆英⽂问号) (new!)
  7. 回⻋

连接符的说明

  1. 连接符 可以 出现在⼀⾏⼀个单词中间,如:post-graduate,这样算
    作⼀个单词(不忽略’-’,具体请看例⼦)⽽不是两个分开的单词
  2. 连接符 不会 出现在单词的 第⼀个字符或最后⼀个字符 ,即 保证输⼊
    中 不存在形如 -all 或者 post- 的单词
  3. 忽略连接符的情况:连接符 也可以 出现在⾏末,⽤来连接下⼀⾏的第
    ⼀个字符串(保证输⼊中 下⼀⾏只会以字⺟开头或为空),并视为 ⼀
    个单词 ,统计此单词时应 忽略 此连接符
  4. 每个单词中最多出现⼀个连接符(第⼀种连接符),即统计后单词表中不
    存在形如aaa-bbb-ccc-ddd…的单词
    时,

输出格式

将文本的每个单词转成全⼩写,并按字典序输出单词和词频以及出现位置
每n+1⾏输出⼀个单词的信息,n为该单词出现次数,格式为
输出格式

思路

如果是人来做文本的词频统计和位置统计,肯定是一边读文本一边统计。但实际上这里面包含两个步骤,单词分割和统计。如果一边分割一边统计,会导致代码间相互耦合,可读性也差。所以将两部分分开。

实际上,因为要统计位置而且存在换行连接符,所以其实还有一个单词组合的步骤,就是将之前分割出来的单词,如果是因为换行连接符分割成两个或更多单词(一个单词跨多行的情况),就将这两个单词组合。

也就是说: 单词分割, 单词组合, 统计

具体实现(Java)

类的设计:

这里只给出不完整的示意代码,具体实现看个人。
1.定义一个Word类

private String rawword;   //原始单词
private String lowword;	  // 转换为小写后的单词
private ArrayList<Integer> row; // 单词出现的各行数
private ArrayList<Integer> col; // 单词出现的各列数
private int num; // 单词出现次数
  1. 定义一个Line类。
private String rawline;  // 每一行的原始字符串
private int row; // 行号
private Words[] words; //用正则表达式“[ \t\n,.!?]+”分割出单词

注:在分割单词之后,使用IndexOf分别找出个单词的位置,并生成Word类的实例。注意要保证每次开始匹配的位置要在上一次匹配到的单词之后。防止出现
test test这样同一行出现两个相同单词的情况。

  1. TreeMap类
    考虑到要求输出有序,使用lowstr - Word 作为键值对,TreeMap自动排序。

算法

1.单词分割:分别将文本的每一行生成Line()的实例。
2.单词组合:将所有的Line()的Words实例域组合成一个大的链表(Java内置的LinkedList),因为合并时要删除单词,使用链表比较方便。如果某个单词以‘-‘结尾,则与后面的单词合并,如果合并后的单词仍是’-'结尾,则再合并。
3.统计: 将上述链表中元素逐个添加如TreeMap即可。若TreeMap中已存在要添加的key了,则取出对应的value,将value的num++; row,col各增加一个,再放回去即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值