HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

7-3 词频统计 (30 分)

思路

使用java更简单,可以一次读取然后用split进行分割字符串,再进行判断
如果使用c的话只能曲线救国
代码思路:
这个题的难点在于什么时候停止输入,什么时候分割字符。
因为题目的输入可能有几行,不能使用gets,因为分割符号不止是空格和回车,所以scanf也不行。
c里面虽然有可以满足我们要求的输入方式,但是不常用,所有我们需要进行曲线救国:
因为题目要求除了字母和数字和下划线就认为是分隔符;
那么我不再找分割符号,而是只读取“单词”:

  • 我们每次读取一个字符,
    • 如果符合单词的要求,就加到单词中,字符长度+1;
  • -如果不是单词就重置我们单词的长度(长度重置就是认为该单词结束,需要读取下一个单词了)。
    • 如果为“#”就结束输入。

题解

#include <bits/stdc++.h>
using namespace std;
map<string, int> mp;
bool cmp(pair<string, int> a, pair<string, int> b)
{
if (a.second == b.second)
return a.first < b.first;
return a.second > b.second;
}
int main()
{
char c;
string str;
str.clear();
while (scanf("%c", &c) != EOF)//不能用cin
{
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_')
{
if (c >= 'A' && c <= 'Z')//将大写字母转换为小写
c = c - 'A' + 'a';
if (str.length() < 15)//只要没超过15个字母这个单词就可以继续存
{
str += c;
}
}
else if (str.length() > 0)//如果不符合“单词”的要求就重置单词记录下一个单词。
{
mp[str]++;
str.clear();
}
//结束条件,结束条件要写在if (str.length() > 0)的下面
//原因:防止"adsda#"的情况,如果写在上面,这种情况“adsda”就无法读入了
if (c == '#')
break;
}
vector<pair<string, int>> vec(mp.begin(), mp.end());
sort(vec.begin(), vec.end(), cmp); //排序
int llen = vec.size() * 0.1;
cout << vec.size() << endl;
for (int i = 0; i < llen; i++)
{
cout << vec[i].second << ":" << vec[i].first << endl;
}
return 0;
}

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/15629392.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(219)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起