排序字典,每个字母的出现次数

时间:2017-08-17 21:37:25

标签: java algorithm sorting dictionary data-structures

想象一下,我们有一个像{“hello”,“world”,“helloo”}这样的字符串数组,我们需要打印出来:

hello = l:2,h:1,e:1,o:1

helloo = l:2,o:2,h:1,e:1

world = w:1,o:1,r:1,l:1,d:1

正如您所看到的,我们需要一个按字典顺序排序的字典(hello,helloo,world),每个单词显示单词中每个字符的排序出现次数。

Java中存储结果的最佳数据结构是什么?

1 个答案:

答案 0 :(得分:0)

我会使用TreeMap<String, TreeMap<Character, Integer>>,其中外部地图具有自然顺序,内部地图根据字符出现次数和第一个位置进行排序(这与您的示例输出相匹配)。

然后代码如下:

  private static TreeMap<String, Map<Character, Integer>> tokenize(String[] words) {
    TreeMap<String, Map<Character, Integer>> map = new TreeMap<>();
    for (String word : words) {
      Map<Character, Integer> counterMap = new LinkedHashMap<>();
      Map<Character, Integer> positionMap = new LinkedHashMap<>();
      for (int i = 0; i < word.length(); ++i) {
        char ch = word.charAt(i);
        int current = counterMap.getOrDefault(ch, 0);
        counterMap.put(ch, current + 1);
        positionMap.putIfAbsent(ch, i);
      }

      TreeMap<Character, Integer> sortedCounterMap = new TreeMap<>((ch1, ch2) -> {
        int counterCmp = counterMap.get(ch2) - counterMap.get(ch1);
        if (counterCmp != 0) return counterCmp;
        return positionMap.get(ch1) - positionMap.get(ch2);
      });
      sortedCounterMap.putAll(counterMap);

      map.put(word, sortedCounterMap);
    }
    return map;
  }

如果未指定具有相同出现次数的字符的顺序,则可以略微简化内部排序,但想法是相同的:

private static TreeMap<String, Map<Character, Integer>> tokenize(String[] words) {
    TreeMap<String, Map<Character, Integer>> map = new TreeMap<>();
    for (String word : words) {
      Map<Character, Integer> counterMap = new LinkedHashMap<>();
      for (int i = 0; i < word.length(); ++i) {
        char ch = word.charAt(i);
        int current = counterMap.getOrDefault(ch, 0);
        counterMap.put(ch, current + 1);
      }

      TreeMap<Character, Integer> sortedCounterMap = new TreeMap<>((ch1, ch2) -> {
        int counterCmp = counterMap.get(ch2) - counterMap.get(ch1);
        if (counterCmp != 0) return counterCmp;
        return ch1 - ch2;
      });
      sortedCounterMap.putAll(counterMap);

      map.put(word, sortedCounterMap);
    }
    return map;
  }