输出一行字符,统计出现词的频率。
输入格式:
输出一行字符,用gets()读入,不超过80个字符。每个单词用一个或多个空格分开。单词个数的约定,最多为40个单词,每个单词最长为9。
输出格式:
按出现的顺序输出单词及出现的次数,中间用“:”分隔。每行一个单词及次数。
输入样例:
在这里给出一组输入。例如:
I am a teacher
输出样例:
在这里给出相应的输出。例如:
I:1
am:1
a:1
teacher:1
编写思路:
这道题好像是一道新题,以至于到目前为止我还不能很容易的在网上找到有关此题的答案。受限于个人的水平,当初在完成此题的时候,也费了一些功夫,故在此分享一下解题思路和需要注意的事项:
本题要求统计一句话中出现的单词的数目,总共需要以下步骤:
- 读取这句话的所有内容:
gets
- 按照单词将此句话拆开:主体中的
for
循环 - 对比单词是否出现过,并进行相应的处理:
Judge
- 输出统计的结果:
Output
- 一些难点:
- 最开始我想忽略题目给的提示条件用
scanf
对进行输入,原因无他scanf
在读入字符串的时候,遇到空格就会停止,这样就可以规避将句子拆分拆成单词的步骤,节约工作量。
但是由于无法准确的判断循环退出的条件(当时我想用单词的数目来作为判定条件),所以放弃了这种方法【大家可以尝试一下用
while
能否实现此功能】
- 关于
Clear
函数,最开始我是没用这个函数的,这导致我有一个点一直无法通过,经过检查之后发现是str2
如果不清除的话,仅仅通过覆盖的方式是无法达成字符串赋值的目的的。
比如说希望用
is
去覆盖teacher
,由于后者更长,所以覆盖后的结果为isacher
并不是我们想得到的结果is
。因此在每次记录完之后对字符串进行重新的清理显得比较必要。
通关代码:
#include <stdio.h>
#include <string.h>
int n = -1;
typedef struct //定义结构体
{
char words[20];
int count;
} SET;
void Start(SET *p, int N) //初始化结构体
{
for (int i = 0; i < N; i++)
(p + i)->count = 1;
}
void Judge(SET *p, char *ch) //判断如果存在,则计数+1,不存在,则新增
{
for (int i = 0; i < n + 1; i++)
if (strcmp((p + i)->words, ch) == 0) //如果相等
{
(p + i)->count++;
return;
}
n++;
strcpy((p + n)->words, ch); //赋值
}
void Output(SET *p) //按照规定格式输出
{
for (int i = 0; i < n + 1; i++)
printf("%s:%d\n", (p + i)->words, (p + i)->count);
}
void Clear(char *str) //清除字符串
{
int i = 0;
while (str[i] != '\0')
{
str[i] = '\0';
i++;
}
}
int main()
{
SET sets[50];
Start(sets, 50);
char str1[100], str2[100];
gets(str1);
int len = strlen(str1); //统计长度
for (int i = 0; i < len; i++) //将句子str1转换为单词str2
{
for (int j = i, k = 0; str1[j] != ' '; j++, k++)
{
str2[k] = str1[j];
i++;
if (str1[j] == '\0')
break;
}
if (str2[0]!='\0') //不能为空
Judge(sets, str2); //判断统计单词
Clear(str2); //清楚变量
}
Output(sets); //按照规定格式输出
return 0;
}