题目
不同的人对描述同一种事物的同义词的偏爱程度可能不同。
例如,在说警察时,有人喜欢用 the police,有人喜欢用 the cops。
分析说话方式有助于确定说话者的身份,这在验证诸如和你线上聊天的是否是同一个人十分有用。
现在,给定一段从某人讲话中提取的文字,你能确定他的最常用词吗?
输入格式
输入共一行,包含一个字符串,以回车符 \n 终止。
输出格式
共一行,输出最常用词以及其出现次数。
如果常用词有多个,则输出字典序最小的那个单词。
注意,单词在输出时,必须全部小写。
单词是指由连续的字母和数字构成的,被非字母数字字符或行首/行尾分隔开的,连续序列。
单词不区分大小写。
数据范围
输入字符串长度不超过 1048576,且至少包含一个大小写字母或数字。
输入样例:
Can1: “Can a can can a can? It can!”
输出样例:
can 5

解法:模拟

注意,单词在输出时,必须全部小写。
单词是指由连续的字母和数字构成的,被非字母数字字符或行首/行尾分隔开的,连续序列。
时间复杂度O(n),空间复杂度O(n)

  1. #include <iostream>
  2. #include <unordered_map>
  3. #include <algorithm>
  4. using namespace std;
  5. unordered_map<string, int> h;
  6. string s;
  7. bool check(char c) {
  8. if (c >= '0' && c <= '9') return true;
  9. if (c >= 'a' && c <= 'z') return true;
  10. if (c >= 'A' && c <= 'Z') return true;
  11. return false;
  12. }
  13. char lower(char c) {
  14. if (c >= 'A' && c <= 'Z')
  15. return c - 'A' + 'a';
  16. return c;
  17. }
  18. int main() {
  19. getline(cin, s);
  20. for (int i = 0; i < s.size(); i++) {
  21. if (check(s[i])) {
  22. string word;
  23. int j = i;
  24. while (j < s.size() && check(s[j]))
  25. word += lower(s[j++]);
  26. h[word]++;
  27. i = j;
  28. }
  29. }
  30. string ans;
  31. int cnt = 0;
  32. for (auto it: h) {
  33. if (it.second > cnt || (it.second == cnt && it.first < ans)) {
  34. cnt = it.second;
  35. ans = it.first;
  36. }
  37. }
  38. cout << ans << ' ' << cnt;
  39. return 0;
  40. }