查找给定字符串中字符的重复次数并对其进行排序?

时间:2016-09-09 06:10:08

标签: java collections

问题陈述:查找给定字符串中字母字符的重复(仅来自a-z的所有小写字母),并将它们从最低到最高排序。 如果两个字符具有相同的重复次数,则具有较大ASCII值的字符被认为较小。

虽然问题很简单,但我试图使用Comparator对最终答案进行排序,而不是使用我自己的排序。这是我做的:

    private static void importantString(String context) {
        HashMap<Character, Integer> importance = new HashMap<Character, Integer>();
        String alpha="abcdefghijklmnopqrstuvwxyz";
        for(int i=0; i<26; i++){
            importance.put(alpha.charAt(i),0);
        }
        for(int i=0; i<context.length(); i++){
            char temp = context.charAt(i);
            Integer val = importance.get(temp);
            importance.put(temp,++val);
        }

        //To sort
        ArrayList<Map.Entry<Character, Integer>> l = new ArrayList(importance.entrySet());
        Collections.sort(l, new Comparator<Map.Entry<Character, Integer>>(){
             public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                if (o1.getValue()==o2.getValue()){
                    if (o1.getKey() > o2.getKey()){
                        return -1;
                    }
                    else{
                        return 1;
                        }

                }
                else {
                return o1.getValue().compareTo(o2.getValue());
                }
            }});
        System.out.println(l);
        for (Entry<Character, Integer> m: l){
            System.out.print(m.getKey()+" ");
        }
        System.out.println();
}  

现在,这个definitley适用于较小的测试用例。例如,

但是,我有一个非常大的测试用例这是我得到的(我的排序数组是这个,因为测试用例字符串非常大):

[r=38083, p=38223, v=38223, f=38268, e=38269, u=38306, z=38320, k=38341, g=38342, c=38396, o=38418, q=38418, b=38422, n=38467, x=38476, y=38477, l=38525, m=38534, w=38575, d=38580, a=38619, s=38648, t=38653, h=38787, j=38791, i=38839]  

注意,o = 38418,q = 38418。在这种情况下,'q'的优先级应低于o,因为它具有更高的ASCII值。但它没有反映出来。

对于像oooqqq这样的小型测试用例,我确实得到了正确的结果。任何解释为什么?

2 个答案:

答案 0 :(得分:2)

您的问题是这一行:

if (o1.getValue()==o2.getValue()){

你在这里使用引用相等。由于==的两边都是Integer类型,因此它们会针对引用相等性进行测试,但仅针对值-128 <= value <= 127,这些Integer被保证为相同的对象(请参阅这里用于自动装箱的Integer.valueOfimportance.put(temp,++val);

您可以简单地将其替换为int值的比较:

if (o1.getValue().intValue()==o2.getValue().intValue()){

此外,您还可以使用Integer.compareToCharacter.compareTo

重写该方法
public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
    int res = o1.getValue().compareTo(o2.getValue());
    return res == 0 ? o2.getKey().compareTo(o1.getKey()) : res;
}

答案 1 :(得分:1)

那是因为你没有&#34;等于&#34;在比较器中用于字母的情况,也应使用equals比较整数类,而不是==.

Comparator和排序部分更改为以下内容:

           Collections.sort(l, new Comparator<Map.Entry<Character, Integer>>(){
             public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                if (o1.getValue().equals(o2.getValue())){
                    return -o1.getKey().compareTo(o2.getKey()))                          
                }
                else {
                    return o1.getValue().compareTo(o2.getValue());
                }
            }});
相关问题