首页 > 试题广场 >

字符统计

[编程题]字符统计
  • 热度指数:201346 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。

数据范围:字符串长度满足


输入描述:

一个只包含小写英文字母和数字的字符串。



输出描述:

一个字符串,为不同字母出现次数的降序表示。若出现次数相同,则按ASCII码的升序输出。

示例1

输入

aaddccdc

输出

cda

说明

样例里,c和d出现3次,a出现2次,但c的ASCII码比d小,所以先输出c,再输出d,最后输出a.
     
while True:
    try:
        s=raw_input()
        str1='abcdefghijklmnopqrstuvwxyz'
        str2=str1.upper()
        str3='0123456789'
        s1=str1+str2+str3+" "
        #count1=0
        #count2=0
        ls=[]
        m=""
        for i in s:
            if i in s1:
                m=m+i
                ls.append(s.count(i))
            else:
                continue
        ll=list(set(ls))
        ll.sort()
        ll=ll[::-1]
        mm=[]
        for i in ll:
            l=[]
            for j in m:
                if m.count(j)==i:
                    l.append(j)
            lm=list(set(l))
            lm.sort()
            #lm=lm[::-1]
            mm=mm+lm
        print("".join(mm))
    except:
        break

发表于 2019-08-10 10:28:01 回复(3)
开始遍历一次str使用map保存每个char出现的次数,以char为键,int为值
然后遍历一次map使用treemap保存每个char的次数,以int为键,char为值
最后遍历treemap将每个char保存到stringbuffer中,最后reverse反转输出

这里为什么要使用两个map呢?
因为一个map只是对键进行自然排序,而它的值并不会进行排序,只是根据键做相应的调换;
然后我们使用treemap对出现的次数int进行排序,最终就得到了我们想要得到的升序char列表;

为什么treemap中要使用map.get(c)*128+128-c作为键值?
我个人认为应该与Integer的intValue缓存有关,因为Integer.valueOf缓存了-128~127范围内的int数,进行比较的话会是相等的(个人看法,勿喷可驳)
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.TreeMap;
 
publicclassMain{
     
    publicstaticvoidmain(String[] args)throwsIOException{
        BufferedReader bf = newBufferedReader(newInputStreamReader(System.in));
        String str;
        while((str=bf.readLine()) != null){
            Map<Character, Integer> map = newHashMap<Character, Integer>();
            for(inti=0; i<str.length(); i++){
                charc = str.charAt(i);
                if(map.containsKey(c))
                    map.put(c, map.get(c)+1);
                else
                    map.put(c, 1);
            }
            Map<Integer,Character> res = newTreeMap<Integer,Character>();
            for(Character c: map.keySet()){
                res.put(map.get(c)*128+128-c, c);
            }
            StringBuffer sb = newStringBuffer();
            for(Integer i: res.keySet()){
                sb.append(res.get(i));
            }
            System.out.println(sb.reverse().toString());
        }
        bf.close();
    }
}

编辑于 2017-09-23 15:38:20 回复(6)
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>

using namespace std;

int main()
{
	string str;

	while (cin >> str)
	{
		map<char, int> mci;
		vector<string> vs;
		string temp = "";
		int maxcount = 0;
		for (int i = 0; i < str.size(); i++)
		{
			if (isalpha(str[i]) || isalnum(str[i]) || isspace(str[i]))
			{
				mci[str[i]] = count(str.begin(),str.end(),str[i]);
				maxcount = (maxcount > mci[str[i]]) ? maxcount : mci[str[i]];
			}
		}
		for (int i = maxcount; i > 0; i--)
		{
			map<char, int>::iterator it;
			for (it = mci.begin(); it != mci.end(); it++)
			{
				if (i == it -> second)
				{
					temp = temp + it -> first;
				}
				if (!temp.empty())
				{
					sort(temp.begin(), temp.end());
					vs.push_back(temp);
					temp = "";
				}
			}
		}
		temp = "";
		for (int i = 0; i < vs.size(); i++)
		{
			temp += vs[i];
		}

		cout << temp << endl;
	}

	return 0;
}

发表于 2016-01-10 14:35:02 回复(0)
/*思路:首先,用HashMap<Character,Integer>统计,记录每个字符及其出现次数;
        然后,使用TreeMap<Integer,String>排序,treeMap按Key增量排序,
        所以使用出现次数做key,对应字符串做value;
        这里使用字符串视为了将相同次数的字符存在一起
        输出时,额外对每个字符串排序
*/
import java.util.Scanner;
import java.util.TreeMap;
import java.util.Arrays;
import java.util.HashMap;
public class Main{
	public static TreeMap<Integer,String> count(String s){
		TreeMap<Integer,String> tMap=new TreeMap<Integer,String>();
		HashMap<Character,Integer>hMap=new HashMap<Character,Integer>();
		for(int i=0;i<s.length();i++){
			char key=s.charAt(i);
			if(hMap.containsKey(key)){
				int value=hMap.get(key);
				value++;
				hMap.put(key, value);
			}else{
				hMap.put(key, 1);
			}
		}//对于treemap的key,value 与hashmap相反
		for(Character hkey:hMap.keySet()){ 
                        int hvalue=hMap.get(hkey);
			if(tMap.containsKey(hvalue)){
				String oldv=tMap.get(hvalue)+hkey;
				tMap.put(hvalue,oldv);
			}else{
				tMap.put(hvalue, hkey+"");
			}
		}
		return tMap;
	}
	public static String sort(String s){//对字符串中字符从小到大排序
		String r="";
		char c[]=s.toCharArray();
		Arrays.sort(c);
		for(int i=0;i<c.length;i++){
			r=r+c[i];
		}
		return r;
	}
    public static void main(String args[]){
    	TreeMap<Integer,String> map=new TreeMap<Integer,String>();
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
             String s,r="";
    		s=sc.nextLine();
    		map=count(s);
    		for(Integer c:map.keySet()){
    			String v=map.get(c);
    			v=sort(v);
    			r=v+r;//注意 将出现次数多的 放前面
    		}
    		System.out.println(r);
        }
    }
}

发表于 2017-06-10 18:11:29 回复(1)
/*
字符统计:大小写字母,数字,空格,并按照出现的次数由大到小输出 思路:先数组统计出现的字符及个数,然后用multimap存储,输出时先存储到栈中在输出
以此来保证字符出现次数相同时按照ASCII顺序输出
@Author ZW
*/
#include<iostream>
#include<map>
#include<stack>
#include<string>
using namespace std;

int main() {
	string input;
	multimap<int,char> map_count;
	stack<pair<int,char> > s_count;
	while (getline(cin,input)) {
		int flag[128] = { 0 };
		map_count.clear();
		for (int i = 0; input[i] != '\0'; i++) {
			if (isalpha(input[i]) || isdigit(input[i]) || isspace(input[i]))
				flag[(int)input[i]]++;
		}
		
		for (int j = 0; j < 128; j++)
		{
			if (flag[j] != 0)
				map_count.insert(pair<int,char>(flag[j],(char)j));
		}
		while (!s_count.empty()) s_count.pop();

		for (auto it = map_count.rbegin(); it != map_count.rend(); it++)
		{
			if(s_count.empty())
				s_count.push(pair<int, char>(it->first, it->second));
			else if(it->first == s_count.top().first)
				s_count.push(pair<int, char>(it->first, it->second));
			else {
				while (!s_count.empty())
				{
					cout << s_count.top().second;
					s_count.pop();
				}
				s_count.push(pair<int, char>(it->first, it->second));
			}
		}
		while (!s_count.empty())
		{
			cout << s_count.top().second;
			s_count.pop();
		}
		cout << endl;
	}
	return 0;
}

发表于 2016-09-17 17:53:45 回复(1)
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
int main(){
	string input;
	int str[128] = {0};
	while (getline(cin ,input)){
		for (int i = 0; i < input.length(); i++){
			str[input[i]]++;
		}
		int num = 0;
		for (int i = 0; i < 128; i++){
			if (str[i] != 0){
				num++;
			}
		}
		while (num--){
			int max = 0;
			int temp_i = 0;
			for (int i = 0; i < 128; i++){
				if (max < str[i]){
					max = str[i];
					temp_i = i;
				}
			}
			str[temp_i] = 0;
			cout << (char)temp_i;
		}
        cout<<endl;

	}
	getchar();
	return 0;
}

发表于 2016-05-26 19:36:02 回复(4)
解题思路:利用256int矩阵存储数量即可!
import java.util.Scanner;

public class Main{
     public static void main(String args[]){
        Scanner in = new Scanner(System.in);
        while (in.hasNext()){
            String str = in.next();
            int[] mat = new int[256];
		   for(int i=0;i<str.length();i++){
			   if((str.charAt(i)>='a' && str.charAt(i)<='z')||(str.charAt(i)>='A' && str.charAt(i)<='Z')||(str.charAt(i)>='0' && str.charAt(i)<='9'||str.charAt(i)==' ')){
				   int pos = str.charAt(i);
				   mat[pos]++;
			   }
		   }
		   int max = 0;
		   for(int i =0;i<256;i++){
			   if(mat[i]>max)
				   max = mat[i];
		   }
		   String res = "";
		   for(int j=max;j>0;j--){
			   for(int k=0;k<256;k++){
				   if(mat[k]==j)
					   res+=(char)k;
			   }
		   }
		   System.out.println(res);
        }
        in.close();
     }
}

发表于 2017-07-10 12:17:40 回复(5)
先用Hashmap统计次数,再传入自定义比较器排序
public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String str = in.next();
            HashMap<Character,Integer> map = new HashMap<>();
            for(int i = 0;i < str.length();i++){
                if(map.containsKey(str.charAt(i))){
                    map.put(str.charAt(i),map.get(str.charAt(i)) + 1);
                }else{
                    map.put(str.charAt(i),1);
                }
            }
            Character[] arr = new Character[map.size()];
            int i = 0;
            for(Character c : map.keySet()){
                arr[i++] = c;
            }
            Arrays.sort(arr,new Comparator<Character>(){
                public int compare(Character o1,Character o2){
                    if(map.get(o1) == map.get(o2)){
                        return o1 - o2;
                    }else{
                        return map.get(o2) - map.get(o1);
                    }
                }
            });
            StringBuilder res = new StringBuilder();
            for(int j = 0;j < arr.length;j++){
                res.append(arr[j]);
            }
            System.out.println(res);
        }
    }


发表于 2021-04-17 19:32:47 回复(0)
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main()
{
    string str;
    while(getline(cin,str))
    {
        unordered_map<char,int> count;
        int max=0;
        sort(str.begin(),str.end());//先排个序,为了一会按统计的个数如果相同,要按ASCII码由小到大排序输出
        //开始用unordered_map记录次数
        for(int i=0;i<str.size();i++)
        {
            count[str[i]]++;
            if(count[str[i]]>max)
            {
                max=count[str[i]];
            }
        }
        //以上,次数已记录完毕,注意此时是无序的
        str.erase(unique(str.begin(),str.end()),str.end());//这步非常关键,要把str里重复的字符去掉
        //准备按照unordered_map中的次数输出
        while(max)
        {
            for(int i=0;i<str.size();i++)
            {
                if(count[str[i]]==max){
                    cout<<str[i];
                }
            }
            max--;
        }
        cout<<endl;
    }
    return 0;
}

编辑于 2020-08-04 15:07:05 回复(0)
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
    string str;
    while(cin>>str){
        map<char, int>m;
        string res;
        for(int i = 0; i < str.size(); i++){
            m[str[i]]++;   
        }
        map<char,int>::iterator it = m.begin();
       	map<int, string> m2;
        while(it!=m.end()){
		 	m2[it->second].push_back(it->first);
            ++it;
        }
        map<int, string>::iterator it2 = m2.begin();
        while(it2!=m2.end()){
            sort(it2->second.begin(), it2->second.end(),greater<char>());
            res += it2->second;
            ++it2;
        }
        reverse(res.begin(),res.end());
        cout<<res<<endl;
    }
    return 0;
}

发表于 2016-06-27 11:02:09 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
            
            int[] asii = new int[200];
            
            String s = cin.nextLine();
            for(int i=0; i<s.length(); i++) {
                char c = s.charAt(i);
                int n = (int)c;
                asii[n] ++;
            }
            
            int max =0;
            for(int i=0; i<200; i++) {
                if(asii[i] > max) {
                    max = asii[i];
                }
            }
            
            while(max!=0) {
                
                for(int i=0; i<200; i++) {
                    if(asii[i] == max) {
                        System.out.print((char)i);
                    }
                }
                
                max--;
            }
            System.out.println();
        }
    }
}

发表于 2016-03-27 11:25:09 回复(3)
这里提供一个奇怪的解法,给大家参考,因为题里规定字符串长度在 1-1000 之间,所以不会溢出
import java.util.*;


public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner (System.in);
        String str = scanner.next();
        
        // 0-9,对应ASCII码值48-57;a-z,对应ASCII码值97-122
        char[] arr1 = str.toCharArray();
        int[] arr2 = new int[10 + 26];    // 数字加上小写字母一共只有36个
        int flag = 150;    // 题里要求按照ASCII码由小到大排序,所以需要定义一个常数(大于122且小于1048均可)用来保证升序排列
        String s = "";

        // 遍历字符串,对数组2进行填充
        for (int i = 0; i < arr1.length; i++) {
            // 通过字符的ASCII码值找到对应下标,然后开始计数
            // 除第一次外,每次加1000,这样可以保证根据次数递增,且对1000取余后可还原ASCII码值
            if (arr1[i] < 58) {
                arr2[arr1[i] - 48] += arr2[arr1[i] - 48] == 0 ? flag - arr1[i] : 1000;
            } else {
                arr2[arr1[i] - 87] += arr2[arr1[i] - 87] == 0 ? flag - arr1[i] : 1000;
            }
        }

        // 数组2排序
        Arrays.sort(arr2);

        // 排序以后是升序,题里要求按照个数降序,所以从后向前遍历即可
        for (int i = arr2.length - 1; i >= 0; i--) {
            if (arr2[i] == 0) break;
            s = s + (char) (flag - arr2[i] % 1000);
        }

        System.out.println(s);

    }
}


发表于 2022-07-08 18:42:07 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            order(line);
        }
    }
    private static void order(String str) {
        HashMap<Character,Integer> map = new HashMap<>();
        char[] arr = str.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
        }

        ArrayList<Map.Entry<Character,Integer>> list = new ArrayList<>(map.entrySet());
        list.sort((o1, o2) -> {
            int i = o2.getValue() - o1.getValue();
            if (i == 0) {
                return o1.getKey() - o2.getKey();
            }
            return i;
        });

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i).getKey());
        }
        System.out.println(sb);
    }
}
发表于 2022-04-09 16:10:11 回复(0)
C 一直嵌套 觉得不错点个赞 #define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
    char arr[1001]={0};
    int cnt[128]={0};
    int snt[128]={0};
    int i,j;
    scanf("%s",arr);
    int len=strlen(arr);
    for(i=0;i<len;i++)
    {
        cnt[arr[i]]++;
    }
    for(i=0;i<128;i++)
    {
        if(cnt[i]!=0)
            snt[cnt[i]]=1;
    }
    for(i=len;i>0;i--)
    {
        if(snt[i]==1)
        {
            for(j='0';j<='z';j++)
            {
                if(cnt[j]==i)
                    printf("%c",j);
            }
        }
    }
    return 0;
}

发表于 2022-03-23 01:30:26 回复(0)
先按出现次数总的排序,再在出现次数相同的小组里排序
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<char,int> a, pair<char,int> b){
    return a.second>b.second;
}
bool cmp1(pair<char,int> a, pair<char,int> b){
    return a.first<b.first;
}
int main(){
    string s;
    while(cin>>s){
        vector<int> table(128);
        for(int i=0;i<s.size();i++){
            table[s[i]]++;
        }
        vector<pair<char,int>> count;
        set<char> myset(s.begin(),s.end());
        for(auto it=myset.begin();it!=myset.end();it++){
            count.emplace_back(*it,table[*it]);
        }
        sort(count.begin(),count.end(),cmp);
        int i = 0;
        while(i<count.size()){
            int start = i;
            while(count[i].second==count[i+1].second){
                i++;
            }
            i++;
            sort(count.begin()+start,count.begin()+i,cmp1);
        }
        for(int i=0;i<count.size();i++){
            cout<<count[i].first;
        }
        cout<<endl;
    }
    return 0;
}


发表于 2022-02-06 11:13:06 回复(0)
while True:
    try:
        s=list(input())
        
        ls=list(set(s))
        lc=[]
        for i in ls:
            lc.append(s.count(i))
            
        dic={i:j for i,j in zip(ls,lc)}
        ls.sort()
        
        while True:
            for i in ls:
                if dic[i]==max(lc):
                    print(i,end='')
                    ls.remove(i)
                    lc.remove(dic[i])
                    break
            if lc==[]:
                break
        print()
    except:
        break

发表于 2021-12-09 21:16:18 回复(0)
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s = sc.nextLine();
            //统计字符
            int[] arr = new int[36];
            for(int i=0; i<s.length(); i++){
                char c=s.charAt(i);
                if(c>='a' &&c<='z'){//字母
                    arr[c-'a']++;
                }else{//数字
                    arr[c-'0'+26]++;
                }
            }
            //统计结果存入List集合
            List<Node> list = new ArrayList<>();
            for(int i=0; i<36; i++){
                if(arr[i]!=0){
                    if(i<26){//字母
                        list.add(new Node((char)('a'+i), arr[i]));
                    }else{//数字
                        list.add(new Node((char)('0'+i-26), arr[i]));
                    }
                }
            }
            //排序
            Collections.sort(list, new Comparator<Node>(){
                public int compare(Node a, Node b){
                    if(a.v!=b.v){//根据值排序
                        return b.v-a.v;
                    }else{//值相等根据ASCII码排序
                        return a.k-b.k;
                    }
                }
            });
            //输出结果
            for(int i=0; i<list.size(); i++){
                System.out.print(list.get(i).k);
            }
            System.out.println();
        }
    }
}

class Node{
    char k;
    int v;
    
    public Node(char k, int v){
        this.k=k;
        this.v=v;
    }
}

发表于 2021-08-18 18:18:31 回复(0)
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

bool compare(const pair<char,int> & lhs, const pair<char,int> & rhs)
{
    if(lhs.second == rhs.second) { return lhs.first < rhs.first; }
    else { return lhs.second > rhs.second; }
}

int main()
{
    string s;
    while(cin >> s)
    {
        unordered_map<char,int> m;
        vector<pair<char,int>> v;
        string ans;
        for(auto & c : s)
        {
            ++m[c];
        }
        for(auto it = m.begin(); it != m.end(); ++it)
        {
            v.push_back(*it);
        }
        sort(v.begin(), v.end(), compare);
        for(auto & elem : v)
        {
            ans += elem.first;
        }
        cout << ans << endl;
    }
    return 0;
}

编辑于 2021-07-26 18:18:22 回复(0)
定义一个二维数组res[i][j],i代表字符出现的次数,j代表出现次数为i的字符都有哪些,输出时,i从后往前输出,j从前往后输出,为了保证ASCLL码的有序性,先用map存放每个该保存的字符出现的次数。
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main(){
    string input;
    while(getline(cin,input)){
        vector<vector<char> >res(input.size()+1);
        map<char,int> m;
        for(int i=0;i<input.size();++i){
            if('a'<=input[i]&&input[i]<='z'||'0'<=input[i]&&input[i]<='9') ++m[input[i]];
        }
        for(auto itor=m.begin();itor!=m.end();++itor){
            res[itor->second].push_back(itor->first);
        }
        for(int i=res.size()-1;i>=0;--i){
            for(int j=0;j<res[i].size();++j){
                cout<<res[i][j];
            }
        }
        cout<<endl;
    }
    return 0;
}


发表于 2021-07-23 20:03:46 回复(0)
public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         while(sc.hasNext()) {             String input = sc.nextLine();             Map<Character,Integer> map = new HashMap<>();             // 1.放入hashmap,统计频率             for (int i = 0; i < input.length(); i ++) {                 if (!map.containsKey(input.charAt(i))) {                     map.put(input.charAt(i), 1);                 } else {                     int freq = map.get(input.charAt(i)) + 1;                     map.put(input.charAt(i), freq);                 }             }
            // 2.HashMap转成ArrayList             List<Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character,Integer>>(map.entrySet());             // 3.改写sort中compare()方法
            Collections.sort(list, new Comparator<Entry<Character, Integer>>(){                 public int compare(Entry<Character, Integer> e1, Entry<Character, Integer> e2) {                     // 1)个数大的首先交换位置                     if (e2.getValue() > e1.getValue()) {                         return 1;                     } else if (e1.getValue() == e2.getValue()) {
                    // 2)个数一样,对比ASCII码顺序                         return e1.getKey() - e2.getKey();                     } else {
                    // 3) 个数小的,不交换位置                         return -1;                     }                 }             });
            // 打印ArrayList排序后的结果             for (Entry<Character, Integer> entry : list) {                 System.out.print(entry.getKey());             }             System.out.println();         }         sc.close();     }
发表于 2021-07-10 13:55:50 回复(0)