首页 > 试题广场 >

1071. Speech Patterns (25)

[编程题]1071. Speech Patterns (25)
  • 热度指数:2767 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
People often have a preference among synonyms of the same word. For example, some may prefer "the police", while others may prefer "the cops". Analyzing such patterns can help to narrow down a speaker's identity, which is useful when validating, for example, whether it's still the same person behind an online avatar.

Now given a paragraph of text sampled from someone's speech, can you find the person's most commonly used word?

输入描述:
Each input file contains one test case. For each case, there is one line of text no more than 1048576 characters in length, terminated by a carriage return '\n'. The input contains at least one alphanumerical character, i.e., one character from the set [0-9 A-Z a-z].


输出描述:
For each test case, print in one line the most commonly occurring word in the input text, followed by a space and the number of times it has occurred in the input. If there are more than one such words, print the lexicographically smallest one. The word should be printed in all lower case. Here a "word" is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.
Note that words are case insensitive.
示例1

输入

Can1: "Can a can can a can?  It can!"

输出

can 5
#include<bits/stdc++.h>
using namespace std;
int main(){
	char c;
	int maxt = -1;
	string str, tmp, ans;
	map<string, int> mp;
	getline(cin,str);
	transform(str.begin(), str.end(), str.begin(), ::tolower);
	for(int i = 0; i <= str.size(); i++){
		if((str[i]>='0'&&str[i]<='9') || (str[i]>='a'&&str[i]<='z')){
			tmp += str[i];
		}else if(tmp.size()){
			mp[tmp]++;
			if(mp[tmp] > maxt){
				maxt = mp[tmp];
				ans = tmp;
			}
			if(mp[tmp] == maxt && tmp < ans){
				ans = tmp;
			}
			tmp.clear();
		}
	}
	cout<<ans<<" "<<maxt<<endl;
	return 0;
}

发表于 2019-08-17 09:16:29 回复(0)
#include <iostream> 
#include <map>
#include <string>
using namespace std;
map<string,int> count;
int main(){
    string s,temp;
    getline(cin,s); //有空格用getline
    for(int i=0;i<s.size();i++){
        while((s[i]>='A'&&s[i]<='Z') || (s[i]>='a'&&s[i]<='z') || (s[i]>='0'&&s[i]<='9')){ //若为有效字符,内部遍历
            if(s[i]>='A'&&s[i]<='Z')
                s[i]='a'+(s[i]-'A');
            temp+=s[i];
            i++;
        }
        if(!temp.empty()){ //若形成了一个有效单词
            if(count.find(temp)==count.end()) count[temp]=0; //不在map内,先初始化
            count[temp]++;
            temp.clear();  //清空暂时单词字符串
        }
    }
    string res;
    int max=0;
    for(map<string,int>::iterator it=count.begin();it!=count.end();it++){ //遍历map查找出现最多的单词
        if(it->second >max){
            res=it->first;
            max=it->second;
        }
    }
    cout<<res<<" "<<max;
    return 0;
}

发表于 2018-03-08 16:25:00 回复(0)

这道题其实就是统计单词个数,输出出现次数最多的单词。

首先是分词,按题目要求将句子分成单个词,
然后可以直接使用hash来统计出现的次数。

需要说明的一点是,使用string 作为 map 的key 时,在插入时已经按string的字典序排列好了,所以最后只需要输出第一个次数最多的单词即可。

代码如下:
#include<iostream>
#include<string>
#include<map>

using namespace std;

int main(){
    string str;
	getline(cin, str);
	str += " ";    //为后面便于分词,在最后加上一个空格
	map < string,int> hash;

	bool isword = false;
	int start = 0;
	int end = 0;
	int max = 0;
	for (int i = 0; str[i] != 0; i++)
	{
		if ((str[i]>='0' && str[i]<='9') || (str[i]>='a' && str[i]<='z')
			|| (str[i]>='A' && str[i]<='Z'))
		{
			if (str[i]>='A' && str[i]<='Z')    //转换为小写
				str[i] = str[i] - 'A' + 'a';
			if (isword == false)
			{
				start = i;
				isword = true;
			}
		}
		else
		{
			if (isword == true)
			{
				end = i;
                string strtmp = str.substr(start, end-start);
                if (hash.find(strtmp) == hash.end())    //计数
					hash[strtmp] = 1;
				else
					hash[strtmp]++;
                
				int tmp = hash[strtmp];
				max = max > tmp ? max : tmp;    //最多的次数
				isword = false;
			}
		}
	}
	for (auto it = hash.cbegin(); it != hash.cend(); it++)
	{
		if (it->second == max)    //输出出现次数最多的词
		{
			cout << (it->first).c_str() << " " << it->second << endl;
                 break;
		}
	}
}

编辑于 2015-08-19 22:16:15 回复(0)
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <string>
#include <map>
using namespace std;

#define MAX 1048576
#define _INF 10000009

string s;
map<string, int> cnt;
multiset<string> lexi;

bool isAlp(char c) {
	return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9'));
}

void lowercase(string& x) {
	for (int i = 0; i < x.size(); ++i) {
		if (('A' <= x[i] && x[i] <= 'Z'))x[i] = x[i] + 'a' - 'A';
	}
}

; int main()
{
	getline(cin, s); lowercase(s);
	string tmp; int i = 0; 
	while (i<s.size()) {
		tmp = ""; 
		while(isAlp(s[i]))tmp.insert(tmp.end(), s[i++]);
		i++; 
		if (tmp.size() > 0)cnt[tmp]++;
	}
	int max = 0;
	for (auto it = cnt.begin(); it != cnt.end(); ++it) {
		if (max < it->second) {
			max = it->second;
			lexi.clear(); lexi.insert(it->first);
		}
		else if (max == it->second)lexi.insert(it->first);
	}
	auto minlexi = lexi.begin();
	cout << *minlexi << " " << cnt[*minlexi];
	
	return 0;
}


发表于 2020-12-04 18:11:22 回复(0)
关键点:
1. 使用transform将字符全部变为小写
2. 使用 map<string, int>
3. 使用string.substr() 取单词
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
int main(){
    char c;
    int maxt = -1;
    string str, tmp, ans;
    map<string, int> mp;
    getline(cin,str);
    transform(str.begin(), str.end(), str.begin(), ::tolower);
    int j = 0;
    for(int i = 0; i <= str.size(); i++){
        if((str[i]>='0'&&str[i]<='9') || (str[i]>='a'&&str[i]<='z')){
            continue;
        }
        else
        {
            if(i > j) {
                tmp = str.substr(j, i-j);
                if (mp.find(tmp) == mp.end()) {
                    mp.insert({tmp, 1});
                } else
                    mp[tmp]++;
            }
            j = i + 1;
        }
    }
    // get answer 
    for(map<string, int>::iterator it = mp.begin(); it != mp.end(); it++)
    {
        if(maxt < 0 || it->second > maxt)
        {
            ans = it->first;
            maxt = it->second;
        }
    }
    cout<<ans<<" "<<maxt<<endl;
    return 0;
}


发表于 2020-07-21 08:23:08 回复(0)
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String[] words = in.nextLine().toLowerCase().split("[^a-zA-Z0-9]+");
		Map<String, Integer> map = new HashMap<String, Integer>();
		for(int i = 0;i<words.length;i++){
			Integer count = map.get(words[i]);
			count = count == null ? 0 : count; 
			map.put(words[i],count+1);
		}
		int max = 0;
		String result = null;
		for (Entry<String, Integer> entry : map.entrySet()) {
			if(entry.getValue()>max){
				max = entry.getValue();
				result = entry.getKey();
			}else if(entry.getValue()==max){
				result = result.compareTo(entry.getKey())<0?result:entry.getKey();
			}
		}
		System.out.println(result+" "+max);
	}
}

发表于 2016-07-25 19:49:44 回复(0)
#include<bits/stdc++.h>
using namespace std;

map<string,int> c;

bool check(char c) {
	if('A'<=c&&c<='Z') return 1;
	if('a'<=c&&c<='z') return 1;
	if('0'<=c&&c<='9') return 1;
	return 0;
}

int main() {
    ios::sync_with_stdio(0);
	string str,ans;
	getline(cin,str);
	int l=str.size(),i=0;
	while(i<l) {
		string word;
		while(check(str[i])&&i<l) {
			if(str[i]>='A'&&str[i]<='Z'){
				str[i]+=32;
			}
			word+=str[i];
			i++;
		}
		if(word!="") c[word]++;
		while(!check(str[i])&&i<l) {
			i++;
		}
	}
	int Max=0;
	for(auto it=c.begin(); it!=c.end(); it++) {
		if(Max<it->second) {
			Max=it->second;
			ans=it->first;
		}
	}
	cout<<ans<<" "<<Max<<endl;
	return 0;
}

发表于 2022-11-19 23:00:23 回复(0)
//就想记录2个问题,关于读题和unordered_map 与 map 的问题:
//题中明显说了,如果个数相同,要首字母最小的那个,也就是字典序最小的那个
//因此,再无脑用unordered_map, 就是错的,所以必须用map, 
//unordered_map 是无序的hash表存储方式,而map是会自动排序的RB-tree 的存储方式。
//铭记于心
#include<iostream>
#include<map>
#include<string>
using namespace std;

const int N=1148576;

void get_string(string &s,map<string,int>&maps){
    string temp="";
    for(int i=0;i<s.size();i++){
        if(isdigit(s[i])){
            temp+=s[i];
            if(i==s.size()-1) maps[temp]++;
        }
        else if(isalpha(s[i])){
            temp+=(tolower(s[i]));
            if(i==s.size()-1) maps[temp]++;
        }
        else{
            if(temp!=""){
                maps[temp]++;
            }
            temp="";
        }
    }
}

int main(){
    string s;
    getline(cin,s);
    map<string,int>maps;
    get_string(s, maps);
    string res;
    int mar=0;
    for(auto i:maps){
        if(mar<i.second){
            res=i.first;
            mar=i.second;
        }
    }
    cout<<res<<" "<<mar<<endl;;
    
    return 0;
}


发表于 2020-12-26 15:28:12 回复(0)
//Speech Patterns (25分)
#include <iostream>
(720)#include <map>
#include <vector>
(721)#include <algorithm>

using namespace std;
string cha, temp = "", maxcha = "";
int in = 0, maxnum = -1;
map<string, int> arrays;

int main() {
    getline(cin, cha);
    while (in <= cha.size()) {
        if (isalnum(cha[in])) {
            if (isupper(cha[in])) cha[in] += 32;
            temp += cha[in];
        } else {
            if (temp != "") {
                arrays[temp]++;
                if (arrays[temp] > maxnum) {
                    maxnum = arrays[temp];
                    maxcha = temp;
                } else if (arrays[temp] == maxnum) {
                    if (temp < maxcha) maxcha = temp;
                }
                temp = "";
            }
        }
        in++;
    }
    printf("%s %d", maxcha.c_str(), maxnum);
}

发表于 2020-04-20 21:32:43 回复(0)
//形成单词的时候要判断其是否为空,否则最后找出来可能是空白字符最多。。。
#include<iostream>
(720)#include<vector>
#include<map>// 0 -48-57   A-65 a-97  
(2941)#include<limits.h>
using namespace std;
map<string,int>mymap;
int main(){
    string s;
    //cin>>s;有空格不能用cin
    getline(cin,s);
    string word="";
    for(int i=0;i<s.size();i++){
        if(s[i]<'0'||(s[i]>'9'&&s[i]<'A')
           ||(s[i]>'Z'&&s[i]<'a')||s[i]>'z'){
         if(!word.empty()){ 
            if(mymap.find(word)==mymap.end()){
                mymap[word]=1;
            }
            else{
                mymap[word]++;
            }
            word="";
         }
        }
        else{
            if(s[i]>='A'&&s[i]<='Z'){
                s[i]=s[i]-'A'+'a';
            }
            word=word+s[i];
        }   
    }
    int max=INT_MIN;
    map<string ,int>::iterator it;
    string ans;
    for(it=mymap.begin();it!=mymap.end();it++){
        if(it->second>max){//mao默认按字典顺序排序
           ans=it->first;
           max=it->second;
        }
    }
    printf("%s %d",ans.c_str(),max);
}


发表于 2020-03-19 11:44:11 回复(0)
贴一个结果对的(我也不知道对不对。。。但试了几个例子都是对的)但是段错误的代码。。。啊啊啊啊我好像特别喜欢写很复杂的代码,优化方面真的很欠缺,能请广大网友看看可以怎样修改吗😭😭😭😭
            
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cctype>
using namespace std;
 
 
vector<string> vt;
 
int main(){
    int k,l;
    int num = 0;
    string str;
    getline(cin,str);
    
    string s1;
  
    for(int i = 0;i < str.size();i++){
        str[i] = tolower(str[i]);
        if(str[i] >= 'a' && str[i] <= 'z' && i != 0){
            if((str[i + 1] >= 'a' && str[i + 1] <= 'z') && str[i - 1] == ' '){
                k = i;
            }
            for(int j = k;j < str.size();j++){
                 if(str[j] >= 'a' && str[j] <= 'z'){
                     if((str[j - 1] >= 'a' && str[j - 1] <= 'z') && str[j + 1] == ' '){
                         l = j;
                          
                             num = l - k + 1;
                             s1 = str.substr(k,num);
                             vt.push_back(s1);
                     }
                 }
            }
        }
    }
    int count[1048576] = {0};
   int x;
    int min = vt[0].size();
    int max = 0;
    
    for(int i = 0;i < vt.size();i++){
         
        int nm = vt[i].size();
    for(int j = 0;j < str.size();j++){
        
        string s2 = str.substr(j,nm);
        if(strcmp(vt[i].c_str(),s2.c_str()) == 0 && (str[j + nm] < 'a' || str[j + nm] >'z') && (str[j + nm] < '1' || str[j + nm] > '9'))
        count[i]++;
    }
     if(count[i] > 1 && vt[i].size() > 1){
            if(max < count[i]){
                max = count[i];
                for(int j = i;j < vt.size();j++){
                    if(count[j] == max && vt[j].size() < vt[i].size()){
                        x = j;
                    }else x = i;
                }
            }
             
        }
    }
    
    cout << vt[x] << " " << count[x];
    return 0;
}


编辑于 2019-08-28 07:05:20 回复(0)
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#include <vector>
bool compare(const std::pair<std::string,int> &a, const std::pair<std::string,int> &b){
 if(a.second!=b.second)
  return a.second > b.second;
 else
  return a.first<b.first;
}
int main(){
 std::map<std::string, int> strcnt;
 std::string strin;
 char a[1048579],c;
 int i=0;
 
 while((c=getchar())!='\n'){
  if((c>='0'&&c<='9')||(c>='a'&&c<='z')||(c>='A'&&c<='Z'))
   a[i++] = c;
  else if(i>0){
   a[i] = '\0';
   strin = a;
   std::transform(strin.begin(),strin.end(),strin.begin(),::tolower);
   strcnt[strin] += 1;
   i=0;
  }
 }
 std::vector<std::pair<std::string,int> > strcntv(strcnt.begin(),strcnt.end());
 std::sort(strcntv.begin(),strcntv.end(),compare);
 std::cout<<strcntv[0].first<<" "<<strcntv[0].second<<std::endl;
}
以上代码可以可以通过牛客网的测试,但在浙大PAT1071却在一个测试点出现段错误,请问有人知道原因吗
发表于 2019-08-07 22:54:41 回复(0)

开始打代码前自信心不够,总是怕理解错题意,另一方面怀疑自己的方法是否会超时,不过幸好最后证实这样的疑虑是多余的。

MY CODE:

#include<iostream>
#include<stdio.h>
#include<string>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 1048579;
char input[maxn];

int check(char c){
    if (('0' <= c && c <= '9') || ('a' <= c && c<='z') || ('A' <= c && c <= 'Z')){
        if ((c >= 'A' && c <= 'Z')) return 1;    //需要转成小写
        return 2;
    }
    return -1;//无效字符用空格代替
}

int main(){
    cin.getline(input, maxn);
    //预处理字符串
    for (int i = 0; input[i] != '\0'; i++){
        int res = check(input[i]);
        if (res == -1) input[i] = ' ';
        else if (res == 1) input[i] -= ('A'-'a');
    }
    //逐个取出单词,加入map
    map<string, int>simap;
    string temp;
    int maxnum = 0;
    for (int i = 0; input[i] != '\0'; i++){
        if (input[i] == ' ' && temp != ""){
            simap[temp]++;
            maxnum = max(maxnum, simap[temp]);
            temp = "";
        }
        if(input[i]!=' ')temp.push_back(input[i]);
    }
    //找到字典序最小的那个字符串
    vector<string> svec;
    for (auto i : simap){
        if (i.second == maxnum) svec.push_back(i.first);
    }
    sort(svec.begin(), svec.end());
    cout << svec[0] << " " << maxnum << endl;
    return 0;
}




编辑于 2019-04-08 22:59:55 回复(0)
import re
from collections import Counter
lst = []
word=re.findall('[0-9a-z]+',input().lower())
c = Counter(word).items()
m = max(c,key=lambda x:x[1])[1]
for i in c:
    if i[1]==m:
        lst.append(list(i))
lst.sort(key=lambda x:(x[0]))
print(lst[0][0]+" "+str(lst[0][1]))

发表于 2018-12-06 23:24:08 回复(0)
import re
from collections import Counter
word=re.findall('[0-9a-z]+',input().lower())
C=Counter(word).items()
m=max(C,key=lambda x:x[1])[1]
res=sorted(filter(lambda x:x[1]==m,C),key=lambda x:x[0])[0]
print(res[0],res[1])

发表于 2018-09-01 13:46:17 回复(0)
好久没有看到这么通俗易懂的问题了
热泪盈眶
思路: 问题的问法就是求  最长使用的单词,分割然后就频率即可
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <map>
using namespace std;

#ifndef debug
ifstream ifile("case.txt");
#define cin ifile
#endif

char Tolower(char x)
{
    if (x >= 'a' && x <= 'z')
    {

    }
    else if (x >= 'A' && x <= 'Z')
    {
        x = 'a' + x - 'A';
    }
    else if (x >= '0' && x <= '9')
    {

    }
    else
    {
        x = ' ';
    }
    return x;
}

int main()
{
    string str;
    getline(cin, str);
    map<string, int> mp;
    transform(str.begin(), str.end(), str.begin(), Tolower);
    //cout << str << endl;
    string tmp;
    for (int i = 0; i < str.size(); i++)
    {
        if (str[i] != ' ')
            tmp += str[i];
        else
        {
            mp[tmp]++;
            tmp = "";
        }
    }
    if (str[str.size() - 1] != ' ')
    {
        mp[tmp]++;
        tmp = "";
    }
    mp[""] = 0;
    int max = 0;
    for (auto it = mp.begin(); it != mp.end(); it++)
    {
        if (it->second > max)
        {
            max = it->second;
        }
    }
    for (auto it = mp.begin(); it != mp.end(); it++)
    {
        if (it->second == max)
        {
            cout << it->first<<" ";
            break;
        }
    }
    cout << max << endl;
    system("pause");
}

发表于 2018-08-28 15:35:02 回复(0)

第一次用 map。。。这道题想不出别的办法了。

# include <string>
# include <map>
# include <cstdio>
# include <cstring>
# include <iostream>

using namespace std;

typedef map<string, int> str_int_map;

char c;
string w;

int main() {
    str_int_map myMap;

    while((c = getchar()) != '\n') {
        if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
            w += c; //string, += 
        }
        else if (c >= 'A' && c <= 'Z') { //小写
            w += (c - 'A' + 'a');
        }
        else if(! w.empty()){
            if (myMap.find(w) == myMap.end()) {
                myMap[w] = 1;
            }
            else {
                myMap[w] ++;
            }
            w.clear();
        }
    }
    if (!w.empty()) {
        if (myMap.find(w) == myMap.end()) {
            myMap[w] = 1;
        }
        else {
            myMap[w] ++;
        }
    }

    str_int_map::iterator iter;
    string maxWord;
    int maxTime = 0;
    for (iter = myMap.begin(); iter != myMap.end(); iter++) {
        if (iter->second > maxTime) {
            maxTime = iter->second;
            maxWord = iter->first;
        }
    }

    cout << maxWord << " " << maxTime;

    return 0;
}
发表于 2018-03-15 19:50:34 回复(0)
//最开始读错题了wa哭😭。
//给组测试样例:
//输入:1Abc:?1Abc
//输出 1Abc 2
#include <bits/stdc++.h>
using namespace std;
map<string,int> mp;
int main(){
    char ch;string tmp;
    while(scanf("%c",&ch)){
        if(ch=='\n'){
            if(tmp.size()) ++mp[tmp];
            break;
        } 
        if(isalnum(ch)) tmp+=tolower(ch);
        else{ 
            if(tmp.size()) ++mp[tmp];
            tmp="";
        }    
    }
    string ans;int maxcnt=0;
    for(auto &c:mp){
        if(c.second>maxcnt) maxcnt=c.second,ans=c.first;
    }
    cout<<ans<<" "<<maxcnt<<endl;
    return 0;
} 

发表于 2018-03-09 23:19:43 回复(0)
我没通过的这个测试用例到底是什么意思?
发表于 2018-03-08 20:14:17 回复(0)
#include <map>
#include <string>
#include <iostream>
using namespace std;
map<string, int> word2cnt;

bool is_alpha(char c){
	if((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z'))
		return true;
	else
		return false;
}

int main(){
	string str;
	getline(cin, str);
	int max_cnt = 0;
	int len = str.size();
	int start = 0, end = 0;
	bool is_word = false;
	for(int i=0; i<len; i++){
		if(is_alpha(str[i])){
			if(str[i] >='A' && str[i] <= 'Z'){
				str[i] = str[i] - 'A' + 'a';
			}
			if(!is_word){
				start = i;
				is_word = true;
			}
		}
		else{
			if(is_word){
				end = i;
				string words = str.substr(start, end-start);
				if(word2cnt.count(words)) word2cnt[words] += 1;
				else word2cnt[words] = 1;
				max_cnt = (max_cnt > word2cnt[words]) ? max_cnt : word2cnt[words];
				is_word = false;
			}
		}
	}
	for(auto iter = word2cnt.begin(); iter != word2cnt.end(); iter++){
		if(iter -> second == max_cnt){
			cout << (iter -> first) << " "<< max_cnt << endl;
			break;
		}
	}
	return 0;
}

发表于 2017-09-01 15:27:22 回复(0)