题目 1556: 统计单词数

题目

统计输入英文文章段落中不同单词(单词有大小写之分, 但统计时忽略大小写)各自出现的次数。 输入段落中所含单词的总数不超过100,最长单词的长度不超过20个字母.

输入
一个包含若干句子的段落, 每个句子由若干英文单词组成. 除空格, 逗号和句号外, 这些输入的句子中不含其他非字母字符, 并且, 逗号和句号紧跟在它前面的英文单词后面, 中间没有空格. 段落最后一个字符是回车符, 表示输入结束.

输出
若段落中共有M个不同的英文单词,则按照其在段落中出现的先后顺序输出M行,各行的格式为: 单词中所有字母均用大写形式输出(最长的单词顶格输出,它前面没有多余的空格;其余单词与其右对齐)+冒号+N个*号+该单词在段落中的出现次数N

样例输入

This  is  a  test.  This  test  is  easy.  This  is  a  test.  This  test  is  easy. 

样例输出

THIS:****4
  IS:****4
   A:**2
TEST:****4
EASY:**2

解题思路

本题类似于PAT乙级1080:MOOC期终成绩。该类题目都是统计一个对象的多个属性,故需要用到qsort和bsearch函数,前者用于对该对象按照某一、或者多个属性排序,后者用于查找该对象是否曾经出现过。
这类题目的解题思路都是利用结构体数组存储每一个对象,在main当中不断的读入信息,先查找该信息的对象是否已经“建档”(即存在于结构体数组中),如果是,将该对象对应的属性更新,否则,重新为该对象“建档”。最后,再按照要求输出即可。

易错点

使用bsearch(二分法查找)前应先使用qsort。

代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct words{
    char name[21];//单词内容
    int n;//出现次数
    int th;//出现顺序
};

int cmp1(const void *a, const void *b){
    struct words c = *(struct words *)a;
    struct words d = *(struct words *)b;
    return strcmp(c.name,d.name);
}

int cmp2(const void *a, const void *b){
    char *c = (char *)a;
    struct words d = *(struct words *)b;
    return strcmp(c,d.name);
}


int cmp3(const void *a, const void *b){//按照出现顺序排序
    struct words c = *(struct words *)a;
    struct words d = *(struct words *)b;
    return c.th - d.th;
}

int main()
{
    struct words W[100];//所含单词的总数
    struct words *p;
    char temp[21];
    int num = 0;
    int i,j,len,max_len = 0;
	while (scanf("%s",temp)!=EOF){
	    len = strlen(temp);
	    while (temp[len-1]==',' || temp[len-1]=='.'){//删除句末的标点符号
	        temp[--len] = '\0';
	    }
	    if (len>max_len)
	        max_len = len;//找到最长长度的单词
	    for (i=0;i<len;i++)//转为大写字母
	        if (temp[i]>96 && temp[i]<123)
	            temp[i]-=32;
	    qsort(W,num,sizeof(W[0]),cmp1);
	    p = (struct words *)bsearch(temp,W,num,sizeof(W[0]),cmp2);
	    if (p==NULL)
	    {
	        W[num].n = 1;
	        strcpy(W[num].name,temp);
	        W[num].th = num;
	        num++;
	    }
	    else
	        (*p).n++;
	}
	qsort(W,num,sizeof(W[0]),cmp3);
	for (i=0;i<num;i++){
	    len = strlen(W[i].name);
	    for (j=0;j<(max_len-len);j++)
	        printf(" ");
	    printf("%s:",W[i].name);
	    for (j=0;j<W[i].n;j++)
	        printf("*");
	    printf("%d\n",W[i].n);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值