java - 使用 HashMap 查找字符串中第二常见的字符

标签 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;
    }

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

最佳答案

在这里,我编写了一个通用实现,它将为您提供 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));
}

关于java - 使用 HashMap 查找字符串中第二常见的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56551608/

相关文章:

java - 为什么我们要创建 PoolableConnectionFactory 对象

java - 架构中的 JAXB 类 : how do I generate a java class containing elements from multiple schemas?

来自数据库的 hibernate 映射中的 Java 日期(时区问题和夏令时)

java - 漏洞 : parameter 'initialCapacity' of ConcurrentHashMap's construct method?

java - 尝试从 zookeeper 节点 : (KeeperErrorCode: ConnectionLoss ) 获取数据时出现异常

java - 单击时更改 ListView 项目背景

Java API - EntrySet() 上的死胡同

java - 从 HashMap 获取值并填充 Java 对象

haskell - 使用惰性文本和字节字符串处理非常大的文本文件

vector - 如何对矢量或 map 中的所有值求和