使用HashMap查找字符串中第二高的字符

时间:2019-06-11 21:00:54

标签: java hashmap

我正在尝试查找字符串中第二常见的字符。下面是我的代码

public class secondCommonAlpha {

    public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {
               second = first;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);
               ans = c;
           }
       }
        return ans;
    }

    public static void main(String[] args) {
        secondCommonAlpha o = new secondCommonAlpha();
        System.out.println(o.secondCommon("bananassss"));
    }
}

在第三次迭代中不起作用。如何修复和优化此代码?

编辑

我使用两个字符变量来完成工作。

public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        Character firstChar = null,secondChar = null;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {

               second = first;
               secondChar = firstChar;
               firstChar = c;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);

               secondChar = c;
           }
       }
        return secondChar;
    }

现在工作正常,但我想这段代码可以优化。

1 个答案:

答案 0 :(得分:1)

在这里,我写了一个通用的实现,它将为您提供n个最常见的字符。根据您的情况,您可以指定2,如示例main中所示。

答案是通过按出现次数(条目的值)对地图条目集进行降序排序,然后从列表的开头选择n-1个索引(从零开始)来实现的。

public static char nMostCommon(String str, int n) {
    Map<Character, Long> counter = str.chars()
        .mapToObj(c -> (char) c)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    if (counter.size() < n) {
        throw new IllegalArgumentException("Not enough different characters.");
    }
    return counter.entrySet().stream()
        .sorted(Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
        .map(Map.Entry::getKey)
        .collect(Collectors.toList())
        .get(n - 1);
}

public static void main(String[] args) {
    System.out.println(nMostCommon("bananassss", 2));
}