题解 | #字符统计#
字符统计
http://www.nowcoder.com/practice/c1f9561de1e240099bdb904765da9ad0
题目的主要信息:
输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。
方法一:
用map建立字符和次数之间的映射,首先遍历一遍字符串统计每个字符出现的次数。总共有n个字符,字符最大出现次数最大为n,从n开始往下遍历,在map中按照ASCII码的大小查找是否有该次数的字符,如果有的话把它加到res中。最后输出res。
具体做法:
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string str;
map<char,int> mp;
while(getline(cin,str))
{
map<char,int> mp;
for(int i=str.size()-1;i>=0;i--){//统计出现次数
mp[str[i]]++;
}
string res;
for(int i=str.size();i>=0;i--)//按照大小排序
{
for(auto x:mp)//按照ASCII码的大小遍历一遍mp
{
if(x.second==i){//如果有字符次数为i的则把该字符添加到res中
res += x.first;
}
}
}
cout<<res<<endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串。
- 空间复杂度:,最坏情况下,每种字符只出现一次,mp需要n个空间。
方法二:
用map建立字符和次数之间的映射,首先遍历一遍字符串统计每个字符出现的次数。然后重载sort函数,对所有映射进行排序,出现次数较大的在前面,若出现次数相同,则ASCII码较大的字符在前面,最后输出排序后的映射的字符。
具体做法:
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<char,int> a,pair<char,int> b){
if(a.second==b.second){//当出现次数相同时
return a.first<b.first;//输出ASCII码较小的字符
}
return a.second>b.second;//输出出现次数较多的字符
}
int main(){
string s;
while(cin>>s){
map<char,int> mp;
for(int i=0;i<s.size();i++){//逐个统计字符出现次数
mp[s[i]]++;
}
vector<pair<char,int> > v(mp.begin(),mp.end());
sort(v.begin(),v.end(),cmp);//按照出现次数进行排序
for(auto it:v){
cout<<it.first;//按照次数大小输出
}
cout<<endl;
}
}
复杂度分析:
- 时间复杂度:,sort函数的时间复杂度为。
- 空间复杂度:,最坏情况下,每种字符只出现一次,mp需要n个空间。