【问题标题】:How to sort a character by number of occurrences in a String using a Map?如何使用 Map 按字符串中出现的次数对字符进行排序?
【发布时间】:2021-04-16 01:24:07
【问题描述】:

我编写的代码计算给定字符串中每个字符的频率并显示它:

Map<Character, Integer> occurrences = new HashMap<>();
char[] chars = str2.toCharArray();
for (char character : chars) {
    Integer integer = occurrences.get(character);
    occurrences.put(character, integer);
    if (integer == null) {
        occurrences.put(character, 1);
    } else {
        occurrences.put(character, integer + 1);
    }
}
System.out.println(occurrences);

现在我想修改我的代码,让它显示按频率排序的字符。从最频繁重复的字符开始,然后是第二频繁,然后是第三,依此类推。

例如,字符串Java 应按以下顺序显示为字符频率:a=2, j=1, v=1

【问题讨论】:

    标签: java string sorting character frequency


    【解决方案1】:

    考虑使用 TreeMap (https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html)

    TreeMap 是一个地图实现,它保持其条目排序 根据其键的自然顺序。

    您可以参考以下代码。

    import java.util.Map;
    import java.util.TreeMap; 
    
    class Test { 
        static void characterCount(String inputString) 
        { 
            TreeMap<Character, Integer> charCountMap = new TreeMap<Character, Integer>(); 
            char[] strArray = inputString.toCharArray(); 
            for (char c : strArray) { 
                if (charCountMap.containsKey(c)) { 
                    charCountMap.put(c, charCountMap.get(c) + 1); 
                } 
                else { 
                    charCountMap.put(c, 1); 
                } 
            } 
            for (Map.Entry entry : charCountMap.entrySet()) { 
                System.out.println(entry.getKey() + "=" + entry.getValue()); 
            } 
        } 
    
        public static void main(String[] args) 
        { 
            String str = "welcometostackoverflow"; 
            characterCount(str); 
        } 
    } 
    

    输出

    a=1
    c=2
    e=3
    f=1
    k=1
    l=2
    m=1
    o=4
    r=1
    s=1
    t=2
    v=1
    w=2
    

    【讨论】:

      【解决方案2】:

      这样试试吧。

      String str = "To be or not to be, that is the question";
      
      • 根据字符和计数流式传输字符和组。
      • 然后重新流式传输条目集以按排序
      • 指定LinkedHashMap 以保留排序顺序。

      条目首先按值(计数)排序。如果计数等于它们,则按键排序。

      Map<Character, Long> map = str.chars()
              .mapToObj(c -> Character.valueOf((char) c))
              .collect(Collectors
                      .groupingBy(c -> c, Collectors.counting()))
              .entrySet().stream()
              .sorted(Entry.<Character, Long>comparingByValue()
                      .reversed().thenComparing(Entry.comparingByKey()))
              .collect(Collectors.toMap(Entry::getKey,
                      Entry::getValue, (a, b) -> a,
                      LinkedHashMap::new));
      
      map.entrySet().forEach(System.out::println);
      

      打印

       =9
      t=6
      o=5
      e=4
      b=2
      h=2
      i=2
      n=2
      s=2
      ,=1
      T=1
      a=1
      q=1
      r=1
      u=1
      

      【讨论】:

        【解决方案3】:

        如果您使用 Map 的 Java 的 TreeMap 实现,它将保持您的 valueskey 排序。

        还有一个构造函数,如果您需要排序方式,您可以在其中传递Comparator 的自定义实现。

        【讨论】:

        • 谢谢。但输出按字母顺序排序。我想按出现次数排序。所以 0=4,然后 e =3 等等
        • @BakytDjumabaev TreeMap 仅对键进行排序。因此,您必须将计数作为键,将字母作为值。这就是为什么我按照我在回答中的方式进行操作的原因。满足您的特定要求。
        • “保持你的排序”中的错字?这是关于对字符及其频率进行排序(在白天和晚上?️)。
        • 虽然你的回答提出了一个实现,但像 Amit's 这样的代码示例会很实用?️
        【解决方案4】:

        您可以收集两张地图:第一张地图汇总数量,然后对其进行排序并收集第二张排序后的地图。在这种情况下,如果 数量 相等,则使用 遭遇顺序

        String str = "JavaProgrammingLanguage";
        
        Map<Character, Integer> occurrences = str.codePoints()
                // Stream<Character>
                .mapToObj(ch -> (char) ch)
                // collect to a map in insertion
                // order, summing up the quantities
                .collect(Collectors.toMap(
                        // key - lowercase character
                        Character::toLowerCase,
                        // value - quantity '1'
                        ch -> 1,
                        // summing quantities
                        Integer::sum,
                        // insertion order
                        LinkedHashMap::new))
                // Stream<Map.Entry<Character,Integer>>
                .entrySet().stream()
                // sort by quantity in reverse order
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                // collect into a sorted map
                .collect(LinkedHashMap::new,
                        (map, entry) -> map.put(entry.getKey(), entry.getValue()),
                        HashMap::putAll);
        
        // output
        System.out.println(occurrences);
        // {a=5, g=4, r=2, m=2, n=2, j=1, v=1, p=1, o=1, i=1, l=1, u=1, e=1}
        

        另见:The intersection of all combinations of n sets

        【讨论】:

          猜你喜欢
          • 2016-08-16
          • 2019-10-17
          • 2017-02-08
          • 2022-11-25
          • 1970-01-01
          • 2018-07-02
          • 2012-03-16
          • 2014-04-23
          • 2014-10-28
          相关资源
          最近更新 更多