CCF计算机职业资格认证 2015年3月第2题 数字排序 解法和思路
问题描写叙述
给定n个整数,请统计出每一个整数出现的次数,按出现次数从多到少的顺序输出。
输入格式
输入的第一行包括一个整数n,表示给定数字的个数。
第二行包括n个整数,相邻的整数之间用一个空格分隔。表示所给定的整数。
第二行包括n个整数,相邻的整数之间用一个空格分隔。表示所给定的整数。
输出格式
输出多行。每行包括两个整数,分别表示一个给定的整数和它出现的次数。
按出现次数递减的顺序输出。假设两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
例子输入
12
5 2 3 3 1 3 4 2 5 2 3 5
5 2 3 3 1 3 4 2 5 2 3 5
例子输出
3 4
2 3
5 3
1 1
4 1
2 3
5 3
1 1
4 1
评測用例规模与约定
1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。
思路:此题不算非常难,最难的点在相等的次数要以值最小的先输出,也就是先按字数降序排列。次数一致的再按整数升序排列,最后输出。
一開始是想着一个TreeMap解决,然后按V值排序,这样提交时,仅仅得70分。有case只是。后面想着还是再写一个类保存num和count吧,再实现comparator接口。
按规则排序就可以。
代码可能不是非常精简,如有更好的方法,能够跟帖说明。
代码例如以下:
package sds; import java.util.*; public class Main { public static void main(String[] args){ //接受输入 Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //得到数组a int[] a = new int[n]; for(int i = 0; i < n; i++){ a[i] = sc.nextInt(); } //统计次数 Map<Integer,Integer> map = new HashMap<Integer, Integer>(); for(int i = 0; i < n; i++){ if(map.get(a[i]) == null){ map.put(a[i],1); }else{ map.put(a[i],map.get(a[i]) + 1); } } ValueComparator bvc = new ValueComparator(); List<NumCount> list = new ArrayList<NumCount>(); //加入到list for(int key:map.keySet()){ NumCount count = new NumCount(key, map.get(key)); list.add(count); } Collections.sort(list, bvc);//排序 //打印 for(int i = 0; i < list.size();i++){ System.out.println(list.get(i).getNum() + " " + list.get(i).getCount()); } } } //实现排序 class ValueComparator implements Comparator<NumCount> { @Override public int compare(NumCount o1, NumCount o2) { if(o1.getCount() > o2.getCount()) return -1;//降序排列 if(o1.getCount() < o2.getCount()) return 1; if(o1.getNum() > o2.getNum()) return 1;//假设次数同样,再按整数升序 if(o1.getNum() < o2.getNum()) return -1; return 0; } } //保存数字和次数 class NumCount{ private int num; private int count; public NumCount(int num,int count) { this.num = num; this.count = count; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }